comparison nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 /*
5 * pkix_pl_string.c
6 *
7 * String Object Functions
8 *
9 */
10
11 #include "pkix_pl_string.h"
12
13 /* --Private-String-Functions------------------------------------- */
14
15 /*
16 * FUNCTION: pkix_pl_String_Comparator
17 * (see comments for PKIX_PL_ComparatorCallback in pkix_pl_system.h)
18 *
19 * NOTE:
20 * This function is a utility function called by pkix_pl_String_Equals().
21 * It is not officially registered as a comparator.
22 */
23 static PKIX_Error *
24 pkix_pl_String_Comparator(
25 PKIX_PL_String *firstString,
26 PKIX_PL_String *secondString,
27 PKIX_Int32 *pResult,
28 void *plContext)
29 {
30 PKIX_UInt32 i;
31 PKIX_Int32 result;
32 unsigned char *p1 = NULL;
33 unsigned char *p2 = NULL;
34
35 PKIX_ENTER(STRING, "pkix_pl_String_Comparator");
36 PKIX_NULLCHECK_THREE(firstString, secondString, pResult);
37
38 result = 0;
39
40 p1 = (unsigned char*) firstString->utf16String;
41 p2 = (unsigned char*) secondString->utf16String;
42
43 /* Compare characters until you find a difference */
44 for (i = 0; ((i < firstString->utf16Length) &&
45 (i < secondString->utf16Length) &&
46 result == 0); i++, p1++, p2++) {
47 if (*p1 < *p2){
48 result = -1;
49 } else if (*p1 > *p2){
50 result = 1;
51 }
52 }
53
54 /* If two arrays are identical so far, the longer one is greater */
55 if (result == 0) {
56 if (firstString->utf16Length < secondString->utf16Length) {
57 result = -1;
58 } else if (firstString->utf16Length >
59 secondString->utf16Length) {
60 result = 1;
61 }
62 }
63
64 *pResult = result;
65
66 PKIX_RETURN(STRING);
67 }
68
69 /*
70 * FUNCTION: pkix_pl_String_Destroy
71 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
72 */
73 static PKIX_Error *
74 pkix_pl_String_Destroy(
75 PKIX_PL_Object *object,
76 void *plContext)
77 {
78 PKIX_PL_String *string = NULL;
79
80 PKIX_ENTER(STRING, "pkix_pl_String_Destroy");
81 PKIX_NULLCHECK_ONE(object);
82
83 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
84 PKIX_ARGUMENTNOTSTRING);
85
86 string = (PKIX_PL_String*)object;
87
88 /* XXX For debugging Destroy EscASCII String */
89 if (string->escAsciiString != NULL) {
90 PKIX_FREE(string->escAsciiString);
91 string->escAsciiString = NULL;
92 string->escAsciiLength = 0;
93 }
94
95 /* Destroy UTF16 String */
96 if (string->utf16String != NULL) {
97 PKIX_FREE(string->utf16String);
98 string->utf16String = NULL;
99 string->utf16Length = 0;
100 }
101
102 cleanup:
103
104 PKIX_RETURN(STRING);
105 }
106
107 /*
108 * FUNCTION: pkix_pl_String_ToString
109 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
110 */
111 static PKIX_Error *
112 pkix_pl_String_ToString(
113 PKIX_PL_Object *object,
114 PKIX_PL_String **pString,
115 void *plContext)
116 {
117 PKIX_PL_String *string = NULL;
118 char *ascii = NULL;
119 PKIX_UInt32 length;
120
121 PKIX_ENTER(STRING, "pkix_pl_String_ToString");
122 PKIX_NULLCHECK_TWO(object, pString);
123
124 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
125 PKIX_ARGUMENTNOTSTRING);
126
127 string = (PKIX_PL_String*)object;
128
129 PKIX_CHECK(PKIX_PL_String_GetEncoded
130 (string, PKIX_ESCASCII, (void **)&ascii, &length, plContext),
131 PKIX_STRINGGETENCODEDFAILED);
132
133 PKIX_CHECK(PKIX_PL_String_Create
134 (PKIX_ESCASCII, ascii, 0, pString, plContext),
135 PKIX_STRINGCREATEFAILED);
136
137 goto cleanup;
138
139 cleanup:
140
141 PKIX_FREE(ascii);
142
143 PKIX_RETURN(STRING);
144 }
145
146 /*
147 * FUNCTION: pkix_pl_String_Equals
148 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
149 */
150 static PKIX_Error *
151 pkix_pl_String_Equals(
152 PKIX_PL_Object *firstObject,
153 PKIX_PL_Object *secondObject,
154 PKIX_Boolean *pResult,
155 void *plContext)
156 {
157 PKIX_UInt32 secondType;
158 PKIX_Int32 cmpResult = 0;
159
160 PKIX_ENTER(STRING, "pkix_pl_String_Equals");
161 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
162
163 /* Sanity check: Test that "firstObject" is a Strings */
164 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_STRING_TYPE, plContext),
165 PKIX_FIRSTOBJECTNOTSTRING);
166
167 /* "SecondObject" doesn't have to be a string */
168 PKIX_CHECK(PKIX_PL_Object_GetType
169 (secondObject, &secondType, plContext),
170 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
171
172 /* If types differ, then we will return false */
173 *pResult = PKIX_FALSE;
174
175 if (secondType != PKIX_STRING_TYPE) goto cleanup;
176
177 /* It's safe to cast here */
178 PKIX_CHECK(pkix_pl_String_Comparator
179 ((PKIX_PL_String*)firstObject,
180 (PKIX_PL_String*)secondObject,
181 &cmpResult,
182 plContext),
183 PKIX_STRINGCOMPARATORFAILED);
184
185 /* Strings are equal iff Comparator Result is 0 */
186 *pResult = (cmpResult == 0);
187
188 cleanup:
189
190 PKIX_RETURN(STRING);
191 }
192
193 /*
194 * FUNCTION: pkix_pl_String_Hashcode
195 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
196 */
197 static PKIX_Error *
198 pkix_pl_String_Hashcode(
199 PKIX_PL_Object *object,
200 PKIX_UInt32 *pHashcode,
201 void *plContext)
202 {
203 PKIX_PL_String *string = NULL;
204
205 PKIX_ENTER(STRING, "pkix_pl_String_Hashcode");
206 PKIX_NULLCHECK_TWO(object, pHashcode);
207
208 PKIX_CHECK(pkix_CheckType(object, PKIX_STRING_TYPE, plContext),
209 PKIX_OBJECTNOTSTRING);
210
211 string = (PKIX_PL_String*)object;
212
213 PKIX_CHECK(pkix_hash
214 ((const unsigned char *)string->utf16String,
215 string->utf16Length,
216 pHashcode,
217 plContext),
218 PKIX_HASHFAILED);
219
220 cleanup:
221
222 PKIX_RETURN(STRING);
223 }
224
225 /*
226 * FUNCTION: pkix_pl_String_RegisterSelf
227 * DESCRIPTION:
228 * Registers PKIX_STRING_TYPE and its related functions with systemClasses[]
229 * THREAD SAFETY:
230 * Not Thread Safe - for performance and complexity reasons
231 *
232 * Since this function is only called by PKIX_PL_Initialize, which should
233 * only be called once, it is acceptable that this function is not
234 * thread-safe.
235 */
236 PKIX_Error *
237 pkix_pl_String_RegisterSelf(
238 void *plContext)
239 {
240 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
241 pkix_ClassTable_Entry entry;
242
243 PKIX_ENTER(STRING, "pkix_pl_String_RegisterSelf");
244
245 entry.description = "String";
246 entry.objCounter = 0;
247 entry.typeObjectSize = sizeof(PKIX_PL_String);
248 entry.destructor = pkix_pl_String_Destroy;
249 entry.equalsFunction = pkix_pl_String_Equals;
250 entry.hashcodeFunction = pkix_pl_String_Hashcode;
251 entry.toStringFunction = pkix_pl_String_ToString;
252 entry.comparator = NULL;
253 entry.duplicateFunction = pkix_duplicateImmutable;
254
255 systemClasses[PKIX_STRING_TYPE] = entry;
256
257 PKIX_RETURN(STRING);
258 }
259
260
261 /* --Public-String-Functions----------------------------------------- */
262
263 /*
264 * FUNCTION: PKIX_PL_String_Create (see comments in pkix_pl_system.h)
265 */
266 PKIX_Error *
267 PKIX_PL_String_Create(
268 PKIX_UInt32 fmtIndicator,
269 const void *stringRep,
270 PKIX_UInt32 stringLen,
271 PKIX_PL_String **pString,
272 void *plContext)
273 {
274 PKIX_PL_String *string = NULL;
275 unsigned char *utf16Char = NULL;
276 PKIX_UInt32 i;
277
278 PKIX_ENTER(STRING, "PKIX_PL_String_Create");
279 PKIX_NULLCHECK_TWO(pString, stringRep);
280
281 PKIX_CHECK(PKIX_PL_Object_Alloc
282 (PKIX_STRING_TYPE,
283 sizeof (PKIX_PL_String),
284 (PKIX_PL_Object **)&string,
285 plContext),
286 PKIX_COULDNOTALLOCATENEWSTRINGOBJECT);
287
288 string->utf16String = NULL;
289 string->utf16Length = 0;
290
291 /* XXX For Debugging */
292 string->escAsciiString = NULL;
293 string->escAsciiLength = 0;
294
295 switch (fmtIndicator) {
296 case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG:
297 PKIX_STRING_DEBUG("\tCalling PL_strlen).\n");
298 string->escAsciiLength = PL_strlen(stringRep);
299
300 /* XXX Cache for Debugging */
301 PKIX_CHECK(PKIX_PL_Malloc
302 ((string->escAsciiLength)+1,
303 (void **)&string->escAsciiString,
304 plContext),
305 PKIX_MALLOCFAILED);
306
307 (void) PORT_Memcpy
308 (string->escAsciiString,
309 (void *)((char *)stringRep),
310 (string->escAsciiLength)+1);
311
312 /* Convert the EscASCII string to UTF16 */
313 PKIX_CHECK(pkix_EscASCII_to_UTF16
314 (string->escAsciiString,
315 string->escAsciiLength,
316 (fmtIndicator == PKIX_ESCASCII_DEBUG),
317 &string->utf16String,
318 &string->utf16Length,
319 plContext),
320 PKIX_ESCASCIITOUTF16FAILED);
321 break;
322 case PKIX_UTF8:
323 /* Convert the UTF8 string to UTF16 */
324 PKIX_CHECK(pkix_UTF8_to_UTF16
325 (stringRep,
326 stringLen,
327 &string->utf16String,
328 &string->utf16Length,
329 plContext),
330 PKIX_UTF8TOUTF16FAILED);
331 break;
332 case PKIX_UTF16:
333 /* UTF16 Strings must be even in length */
334 if (stringLen%2 == 1) {
335 PKIX_DECREF(string);
336 PKIX_ERROR(PKIX_UTF16ALIGNMENTERROR);
337 }
338
339 utf16Char = (unsigned char *)stringRep;
340
341 /* Make sure this is a valid UTF-16 String */
342 for (i = 0; \
343 (i < stringLen) && (pkixErrorResult == NULL); \
344 i += 2) {
345 /* Check that surrogate pairs are valid */
346 if ((utf16Char[i] >= 0xD8)&&
347 (utf16Char[i] <= 0xDB)) {
348 if ((i+2) >= stringLen) {
349 PKIX_ERROR(PKIX_UTF16HIGHZONEALIGNMENTERROR);
350 /* Second pair should be DC00-DFFF */
351 } else if (!((utf16Char[i+2] >= 0xDC)&&
352 (utf16Char[i+2] <= 0xDF))) {
353 PKIX_ERROR(PKIX_UTF16LOWZONEERROR);
354 } else {
355 /* Surrogate quartet is valid. */
356 i += 2;
357 }
358 }
359 }
360
361 /* Create UTF16 String */
362 string->utf16Length = stringLen;
363
364 /* Alloc space for string */
365 PKIX_CHECK(PKIX_PL_Malloc
366 (stringLen, &string->utf16String, plContext),
367 PKIX_MALLOCFAILED);
368
369 PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n");
370 (void) PORT_Memcpy
371 (string->utf16String, stringRep, stringLen);
372 break;
373
374 default:
375 PKIX_ERROR(PKIX_UNKNOWNFORMAT);
376 }
377
378 *pString = string;
379
380 cleanup:
381
382 if (PKIX_ERROR_RECEIVED){
383 PKIX_DECREF(string);
384 }
385
386 PKIX_RETURN(STRING);
387 }
388
389 /*
390 * FUNCTION: PKIX_PL_Sprintf (see comments in pkix_pl_system.h)
391 */
392 PKIX_Error *
393 PKIX_PL_Sprintf(
394 PKIX_PL_String **pOut,
395 void *plContext,
396 const PKIX_PL_String *fmt,
397 ...)
398 {
399 PKIX_PL_String *tempString = NULL;
400 PKIX_UInt32 tempUInt = 0;
401 void *pArg = NULL;
402 char *asciiText = NULL;
403 char *asciiFormat = NULL;
404 char *convertedAsciiFormat = NULL;
405 char *convertedAsciiFormatBase = NULL;
406 va_list args;
407 PKIX_UInt32 length, i, j, dummyLen;
408
409 PKIX_ENTER(STRING, "PKIX_PL_Sprintf");
410 PKIX_NULLCHECK_TWO(pOut, fmt);
411
412 PKIX_CHECK(PKIX_PL_String_GetEncoded
413 ((PKIX_PL_String *)fmt,
414 PKIX_ESCASCII,
415 (void **)&asciiFormat,
416 &length,
417 plContext),
418 PKIX_STRINGGETENCODEDFAILED);
419
420 PKIX_STRING_DEBUG("\tCalling PR_Malloc).\n");
421 convertedAsciiFormat = PR_Malloc(length + 1);
422 if (convertedAsciiFormat == NULL)
423 PKIX_ERROR_ALLOC_ERROR();
424
425 convertedAsciiFormatBase = convertedAsciiFormat;
426
427 PKIX_STRING_DEBUG("\tCalling va_start).\n");
428 va_start(args, fmt);
429
430 i = 0;
431 j = 0;
432 while (i < length) {
433 if ((asciiFormat[i] == '%')&&((i+1) < length)) {
434 switch (asciiFormat[i+1]) {
435 case 's':
436 convertedAsciiFormat[j++] = asciiFormat[i++];
437 convertedAsciiFormat[j++] = asciiFormat[i++];
438 convertedAsciiFormat[j] = '\0';
439
440 tempString = va_arg(args, PKIX_PL_String *);
441 if (tempString != NULL) {
442 PKIX_CHECK(PKIX_PL_String_GetEncoded
443 ((PKIX_PL_String*)
444 tempString,
445 PKIX_ESCASCII,
446 &pArg,
447 &dummyLen,
448 plContext),
449 PKIX_STRINGGETENCODEDFAILED);
450 } else {
451 /* there may be a NULL in var_args */
452 pArg = NULL;
453 }
454 if (asciiText != NULL) {
455 asciiText = PR_sprintf_append(asciiText,
456 (const char *)convertedAsciiFormat,
457 pArg);
458 } else {
459 asciiText = PR_smprintf
460 ((const char *)convertedAsciiFormat,
461 pArg);
462 }
463 if (pArg != NULL) {
464 PKIX_PL_Free(pArg, plContext);
465 pArg = NULL;
466 }
467 convertedAsciiFormat += j;
468 j = 0;
469 break;
470 case 'd':
471 case 'i':
472 case 'o':
473 case 'u':
474 case 'x':
475 case 'X':
476 convertedAsciiFormat[j++] = asciiFormat[i++];
477 convertedAsciiFormat[j++] = asciiFormat[i++];
478 convertedAsciiFormat[j] = '\0';
479
480 tempUInt = va_arg(args, PKIX_UInt32);
481 if (asciiText != NULL) {
482 asciiText = PR_sprintf_append(asciiText,
483 (const char *)convertedAsciiFormat,
484 tempUInt);
485 } else {
486 asciiText = PR_smprintf
487 ((const char *)convertedAsciiFormat,
488 tempUInt);
489 }
490 convertedAsciiFormat += j;
491 j = 0;
492 break;
493 default:
494 convertedAsciiFormat[j++] = asciiFormat[i++];
495 convertedAsciiFormat[j++] = asciiFormat[i++];
496 break;
497 }
498 } else {
499 convertedAsciiFormat[j++] = asciiFormat[i++];
500 }
501 }
502
503 /* for constant string value at end of fmt */
504 if (j > 0) {
505 convertedAsciiFormat[j] = '\0';
506 if (asciiText != NULL) {
507 asciiText = PR_sprintf_append(asciiText,
508 (const char *)convertedAsciiFormat);
509 } else {
510 asciiText = PR_smprintf((const char *)convertedAsciiFormat);
511 }
512 }
513
514 va_end(args);
515
516 /* Copy temporary char * into a string object */
517 PKIX_CHECK(PKIX_PL_String_Create
518 (PKIX_ESCASCII, (void *)asciiText, 0, pOut, plContext),
519 PKIX_STRINGCREATEFAILED);
520
521 cleanup:
522
523 PKIX_FREE(asciiFormat);
524
525 if (convertedAsciiFormatBase){
526 PR_Free(convertedAsciiFormatBase);
527 }
528
529 if (asciiText){
530 PKIX_STRING_DEBUG("\tCalling PR_smprintf_free).\n");
531 PR_smprintf_free(asciiText);
532 }
533
534 PKIX_RETURN(STRING);
535 }
536
537 /*
538 * FUNCTION: PKIX_PL_GetString (see comments in pkix_pl_system.h)
539 */
540 PKIX_Error *
541 PKIX_PL_GetString(
542 /* ARGSUSED */ PKIX_UInt32 stringID,
543 char *defaultString,
544 PKIX_PL_String **pString,
545 void *plContext)
546 {
547 PKIX_ENTER(STRING, "PKIX_PL_GetString");
548 PKIX_NULLCHECK_TWO(pString, defaultString);
549
550 /* XXX Optimization - use stringID for caching */
551 PKIX_CHECK(PKIX_PL_String_Create
552 (PKIX_ESCASCII, defaultString, 0, pString, plContext),
553 PKIX_STRINGCREATEFAILED);
554
555 cleanup:
556
557 PKIX_RETURN(STRING);
558 }
559
560 /*
561 * FUNCTION: PKIX_PL_String_GetEncoded (see comments in pkix_pl_system.h)
562 */
563 PKIX_Error *
564 PKIX_PL_String_GetEncoded(
565 PKIX_PL_String *string,
566 PKIX_UInt32 fmtIndicator,
567 void **pStringRep,
568 PKIX_UInt32 *pLength,
569 void *plContext)
570 {
571 PKIX_ENTER(STRING, "PKIX_PL_String_GetEncoded");
572 PKIX_NULLCHECK_THREE(string, pStringRep, pLength);
573
574 switch (fmtIndicator) {
575 case PKIX_ESCASCII: case PKIX_ESCASCII_DEBUG:
576 PKIX_CHECK(pkix_UTF16_to_EscASCII
577 (string->utf16String,
578 string->utf16Length,
579 (fmtIndicator == PKIX_ESCASCII_DEBUG),
580 (char **)pStringRep,
581 pLength,
582 plContext),
583 PKIX_UTF16TOESCASCIIFAILED);
584 break;
585 case PKIX_UTF8:
586 PKIX_CHECK(pkix_UTF16_to_UTF8
587 (string->utf16String,
588 string->utf16Length,
589 PKIX_FALSE,
590 pStringRep,
591 pLength,
592 plContext),
593 PKIX_UTF16TOUTF8FAILED);
594 break;
595 case PKIX_UTF8_NULL_TERM:
596 PKIX_CHECK(pkix_UTF16_to_UTF8
597 (string->utf16String,
598 string->utf16Length,
599 PKIX_TRUE,
600 pStringRep,
601 pLength,
602 plContext),
603 PKIX_UTF16TOUTF8FAILED);
604 break;
605 case PKIX_UTF16:
606 *pLength = string->utf16Length;
607
608 PKIX_CHECK(PKIX_PL_Malloc(*pLength, pStringRep, plContext),
609 PKIX_MALLOCFAILED);
610
611 PKIX_STRING_DEBUG("\tCalling PORT_Memcpy).\n");
612 (void) PORT_Memcpy(*pStringRep, string->utf16String, *pLength);
613 break;
614 default:
615 PKIX_ERROR(PKIX_UNKNOWNFORMAT);
616 }
617
618 cleanup:
619
620 PKIX_RETURN(STRING);
621 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)