Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: nss/lib/base/nssutf8.c

Issue 1843333003: Update NSPR to 4.12 and NSS to 3.23 on iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 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 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/. */ 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 /* 5 /*
6 * utf8.c 6 * utf8.c
7 * 7 *
8 * This file contains some additional utility routines required for 8 * This file contains some additional utility routines required for
9 * handling UTF8 strings. 9 * handling UTF8 strings.
10 */ 10 */
11 11
12 #ifndef BASE_H 12 #ifndef BASE_H
13 #include "base.h" 13 #include "base.h"
14 #endif /* BASE_H */ 14 #endif /* BASE_H */
15 15
16 #include "plstr.h" 16 #include "plstr.h"
17 17
18 /* 18 /*
19 * NOTES: 19 * NOTES:
20 * 20 *
21 * There's an "is hex string" function in pki1/atav.c. If we need 21 * There's an "is hex string" function in pki1/atav.c. If we need
22 * it in more places, pull that one out. 22 * it in more places, pull that one out.
23 */ 23 */
24 24
25 /* 25 /*
26 * nssUTF8_CaseIgnoreMatch 26 * nssUTF8_CaseIgnoreMatch
27 * 27 *
28 * Returns true if the two UTF8-encoded strings pointed to by the 28 * Returns true if the two UTF8-encoded strings pointed to by the
29 * two specified NSSUTF8 pointers differ only in typcase. 29 * two specified NSSUTF8 pointers differ only in typcase.
30 * 30 *
31 * The error may be one of the following values: 31 * The error may be one of the following values:
32 * NSS_ERROR_INVALID_POINTER 32 * NSS_ERROR_INVALID_POINTER
33 * 33 *
34 * Return value: 34 * Return value:
35 * PR_TRUE if the strings match, ignoring case 35 * PR_TRUE if the strings match, ignoring case
36 * PR_FALSE if they don't 36 * PR_FALSE if they don't
37 * PR_FALSE upon error 37 * PR_FALSE upon error
38 */ 38 */
39 39
40 NSS_IMPLEMENT PRBool 40 NSS_IMPLEMENT PRBool
41 nssUTF8_CaseIgnoreMatch 41 nssUTF8_CaseIgnoreMatch(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt)
42 (
43 const NSSUTF8 *a,
44 const NSSUTF8 *b,
45 PRStatus *statusOpt
46 )
47 { 42 {
48 #ifdef NSSDEBUG 43 #ifdef NSSDEBUG
49 if( ((const NSSUTF8 *)NULL == a) || 44 if (((const NSSUTF8 *)NULL == a) || ((const NSSUTF8 *)NULL == b)) {
50 ((const NSSUTF8 *)NULL == b) ) { 45 nss_SetError(NSS_ERROR_INVALID_POINTER);
51 nss_SetError(NSS_ERROR_INVALID_POINTER); 46 if ((PRStatus *)NULL != statusOpt) {
52 if( (PRStatus *)NULL != statusOpt ) { 47 *statusOpt = PR_FAILURE;
53 *statusOpt = PR_FAILURE; 48 }
49 return PR_FALSE;
54 } 50 }
55 return PR_FALSE;
56 }
57 #endif /* NSSDEBUG */ 51 #endif /* NSSDEBUG */
58 52
59 if( (PRStatus *)NULL != statusOpt ) { 53 if ((PRStatus *)NULL != statusOpt) {
60 *statusOpt = PR_SUCCESS; 54 *statusOpt = PR_SUCCESS;
61 } 55 }
62 56
63 /* 57 /*
64 * XXX fgmr 58 * XXX fgmr
65 * 59 *
66 * This is, like, so wrong! 60 * This is, like, so wrong!
67 */ 61 */
68 if( 0 == PL_strcasecmp((const char *)a, (const char *)b) ) { 62 if (0 == PL_strcasecmp((const char *)a, (const char *)b)) {
69 return PR_TRUE; 63 return PR_TRUE;
70 } else { 64 } else {
71 return PR_FALSE; 65 return PR_FALSE;
72 } 66 }
73 } 67 }
74 68
75 /* 69 /*
76 * nssUTF8_PrintableMatch 70 * nssUTF8_PrintableMatch
77 * 71 *
78 * Returns true if the two Printable strings pointed to by the 72 * Returns true if the two Printable strings pointed to by the
79 * two specified NSSUTF8 pointers match when compared with the 73 * two specified NSSUTF8 pointers match when compared with the
80 * rules for Printable String (leading and trailing spaces are 74 * rules for Printable String (leading and trailing spaces are
81 * disregarded, extents of whitespace match irregardless of length, 75 * disregarded, extents of whitespace match irregardless of length,
82 * and case is not significant), then PR_TRUE will be returned. 76 * and case is not significant), then PR_TRUE will be returned.
83 * Otherwise, PR_FALSE will be returned. Upon failure, PR_FALSE 77 * Otherwise, PR_FALSE will be returned. Upon failure, PR_FALSE
84 * will be returned. If the optional statusOpt argument is not 78 * will be returned. If the optional statusOpt argument is not
85 * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that 79 * NULL, then PR_SUCCESS or PR_FAILURE will be stored in that
86 * location. 80 * location.
87 * 81 *
88 * The error may be one of the following values: 82 * The error may be one of the following values:
89 * NSS_ERROR_INVALID_POINTER 83 * NSS_ERROR_INVALID_POINTER
90 * 84 *
91 * Return value: 85 * Return value:
92 * PR_TRUE if the strings match, ignoring case 86 * PR_TRUE if the strings match, ignoring case
93 * PR_FALSE if they don't 87 * PR_FALSE if they don't
94 * PR_FALSE upon error 88 * PR_FALSE upon error
95 */ 89 */
96 90
97 NSS_IMPLEMENT PRBool 91 NSS_IMPLEMENT PRBool
98 nssUTF8_PrintableMatch 92 nssUTF8_PrintableMatch(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt)
99 (
100 const NSSUTF8 *a,
101 const NSSUTF8 *b,
102 PRStatus *statusOpt
103 )
104 { 93 {
105 PRUint8 *c; 94 PRUint8 *c;
106 PRUint8 *d; 95 PRUint8 *d;
107 96
108 #ifdef NSSDEBUG 97 #ifdef NSSDEBUG
109 if( ((const NSSUTF8 *)NULL == a) || 98 if (((const NSSUTF8 *)NULL == a) || ((const NSSUTF8 *)NULL == b)) {
110 ((const NSSUTF8 *)NULL == b) ) { 99 nss_SetError(NSS_ERROR_INVALID_POINTER);
111 nss_SetError(NSS_ERROR_INVALID_POINTER); 100 if ((PRStatus *)NULL != statusOpt) {
112 if( (PRStatus *)NULL != statusOpt ) { 101 *statusOpt = PR_FAILURE;
113 *statusOpt = PR_FAILURE; 102 }
103 return PR_FALSE;
114 } 104 }
115 return PR_FALSE;
116 }
117 #endif /* NSSDEBUG */ 105 #endif /* NSSDEBUG */
118 106
119 if( (PRStatus *)NULL != statusOpt ) { 107 if ((PRStatus *)NULL != statusOpt) {
120 *statusOpt = PR_SUCCESS; 108 *statusOpt = PR_SUCCESS;
121 }
122
123 c = (PRUint8 *)a;
124 d = (PRUint8 *)b;
125
126 while( ' ' == *c ) {
127 c++;
128 }
129
130 while( ' ' == *d ) {
131 d++;
132 }
133
134 while( ('\0' != *c) && ('\0' != *d) ) {
135 PRUint8 e, f;
136
137 e = *c;
138 f = *d;
139
140 if( ('a' <= e) && (e <= 'z') ) {
141 e -= ('a' - 'A');
142 } 109 }
143 110
144 if( ('a' <= f) && (f <= 'z') ) { 111 c = (PRUint8 *)a;
145 f -= ('a' - 'A'); 112 d = (PRUint8 *)b;
113
114 while (' ' == *c) {
115 c++;
146 } 116 }
147 117
148 if( e != f ) { 118 while (' ' == *d) {
149 return PR_FALSE; 119 d++;
150 } 120 }
151 121
152 c++; 122 while (('\0' != *c) && ('\0' != *d)) {
153 d++; 123 PRUint8 e, f;
154 124
155 if( ' ' == *c ) { 125 e = *c;
156 while( ' ' == *c ) { 126 f = *d;
127
128 if (('a' <= e) && (e <= 'z')) {
129 e -= ('a' - 'A');
130 }
131
132 if (('a' <= f) && (f <= 'z')) {
133 f -= ('a' - 'A');
134 }
135
136 if (e != f) {
137 return PR_FALSE;
138 }
139
157 c++; 140 c++;
158 } 141 d++;
159 c--; 142
143 if (' ' == *c) {
144 while (' ' == *c) {
145 c++;
146 }
147 c--;
148 }
149
150 if (' ' == *d) {
151 while (' ' == *d) {
152 d++;
153 }
154 d--;
155 }
160 } 156 }
161 157
162 if( ' ' == *d ) { 158 while (' ' == *c) {
163 while( ' ' == *d ) { 159 c++;
160 }
161
162 while (' ' == *d) {
164 d++; 163 d++;
165 }
166 d--;
167 } 164 }
168 }
169 165
170 while( ' ' == *c ) { 166 if (*c == *d) {
171 c++; 167 /* And both '\0', btw */
172 } 168 return PR_TRUE;
173 169 } else {
174 while( ' ' == *d ) { 170 return PR_FALSE;
175 d++; 171 }
176 }
177
178 if( *c == *d ) {
179 /* And both '\0', btw */
180 return PR_TRUE;
181 } else {
182 return PR_FALSE;
183 }
184 } 172 }
185 173
186 /* 174 /*
187 * nssUTF8_Duplicate 175 * nssUTF8_Duplicate
188 * 176 *
189 * This routine duplicates the UTF8-encoded string pointed to by the 177 * This routine duplicates the UTF8-encoded string pointed to by the
190 * specified NSSUTF8 pointer. If the optional arenaOpt argument is 178 * specified NSSUTF8 pointer. If the optional arenaOpt argument is
191 * not null, the memory required will be obtained from that arena; 179 * not null, the memory required will be obtained from that arena;
192 * otherwise, the memory required will be obtained from the heap. 180 * otherwise, the memory required will be obtained from the heap.
193 * A pointer to the new string will be returned. In case of error, 181 * A pointer to the new string will be returned. In case of error,
194 * an error will be placed on the error stack and NULL will be 182 * an error will be placed on the error stack and NULL will be
195 * returned. 183 * returned.
196 * 184 *
197 * The error may be one of the following values: 185 * The error may be one of the following values:
198 * NSS_ERROR_INVALID_POINTER 186 * NSS_ERROR_INVALID_POINTER
199 * NSS_ERROR_INVALID_ARENA 187 * NSS_ERROR_INVALID_ARENA
200 * NSS_ERROR_NO_MEMORY 188 * NSS_ERROR_NO_MEMORY
201 */ 189 */
202 190
203 NSS_IMPLEMENT NSSUTF8 * 191 NSS_IMPLEMENT NSSUTF8 *
204 nssUTF8_Duplicate 192 nssUTF8_Duplicate(const NSSUTF8 *s, NSSArena *arenaOpt)
205 (
206 const NSSUTF8 *s,
207 NSSArena *arenaOpt
208 )
209 { 193 {
210 NSSUTF8 *rv; 194 NSSUTF8 *rv;
211 PRUint32 len; 195 PRUint32 len;
212 196
213 #ifdef NSSDEBUG 197 #ifdef NSSDEBUG
214 if( (const NSSUTF8 *)NULL == s ) { 198 if ((const NSSUTF8 *)NULL == s) {
215 nss_SetError(NSS_ERROR_INVALID_POINTER); 199 nss_SetError(NSS_ERROR_INVALID_POINTER);
216 return (NSSUTF8 *)NULL; 200 return (NSSUTF8 *)NULL;
217 } 201 }
218 202
219 if( (NSSArena *)NULL != arenaOpt ) { 203 if ((NSSArena *)NULL != arenaOpt) {
220 if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { 204 if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
221 return (NSSUTF8 *)NULL; 205 return (NSSUTF8 *)NULL;
206 }
222 } 207 }
223 }
224 #endif /* NSSDEBUG */ 208 #endif /* NSSDEBUG */
225 209
226 len = PL_strlen((const char *)s); 210 len = PL_strlen((const char *)s);
227 #ifdef PEDANTIC 211 #ifdef PEDANTIC
228 if( '\0' != ((const char *)s)[ len ] ) { 212 if ('\0' != ((const char *)s)[len]) {
229 /* must have wrapped, e.g., too big for PRUint32 */ 213 /* must have wrapped, e.g., too big for PRUint32 */
230 nss_SetError(NSS_ERROR_NO_MEMORY); 214 nss_SetError(NSS_ERROR_NO_MEMORY);
231 return (NSSUTF8 *)NULL; 215 return (NSSUTF8 *)NULL;
232 } 216 }
233 #endif /* PEDANTIC */ 217 #endif /* PEDANTIC */
234 len++; /* zero termination */ 218 len++; /* zero termination */
235 219
236 rv = nss_ZAlloc(arenaOpt, len); 220 rv = nss_ZAlloc(arenaOpt, len);
237 if( (void *)NULL == rv ) { 221 if ((void *)NULL == rv) {
238 return (NSSUTF8 *)NULL; 222 return (NSSUTF8 *)NULL;
239 } 223 }
240 224
241 (void)nsslibc_memcpy(rv, s, len); 225 (void)nsslibc_memcpy(rv, s, len);
242 return rv; 226 return rv;
243 } 227 }
244 228
245 /* 229 /*
246 * nssUTF8_Size 230 * nssUTF8_Size
247 * 231 *
248 * This routine returns the length in bytes (including the terminating 232 * This routine returns the length in bytes (including the terminating
249 * null) of the UTF8-encoded string pointed to by the specified 233 * null) of the UTF8-encoded string pointed to by the specified
250 * NSSUTF8 pointer. Zero is returned on error. 234 * NSSUTF8 pointer. Zero is returned on error.
251 * 235 *
252 * The error may be one of the following values: 236 * The error may be one of the following values:
253 * NSS_ERROR_INVALID_POINTER 237 * NSS_ERROR_INVALID_POINTER
254 * NSS_ERROR_VALUE_TOO_LARGE 238 * NSS_ERROR_VALUE_TOO_LARGE
255 * 239 *
256 * Return value: 240 * Return value:
257 * 0 on error 241 * 0 on error
258 * nonzero length of the string. 242 * nonzero length of the string.
259 */ 243 */
260 244
261 NSS_IMPLEMENT PRUint32 245 NSS_IMPLEMENT PRUint32
262 nssUTF8_Size 246 nssUTF8_Size(const NSSUTF8 *s, PRStatus *statusOpt)
263 (
264 const NSSUTF8 *s,
265 PRStatus *statusOpt
266 )
267 { 247 {
268 PRUint32 sv; 248 PRUint32 sv;
269 249
270 #ifdef NSSDEBUG 250 #ifdef NSSDEBUG
271 if( (const NSSUTF8 *)NULL == s ) { 251 if ((const NSSUTF8 *)NULL == s) {
272 nss_SetError(NSS_ERROR_INVALID_POINTER); 252 nss_SetError(NSS_ERROR_INVALID_POINTER);
273 if( (PRStatus *)NULL != statusOpt ) { 253 if ((PRStatus *)NULL != statusOpt) {
274 *statusOpt = PR_FAILURE; 254 *statusOpt = PR_FAILURE;
255 }
256 return 0;
275 } 257 }
276 return 0;
277 }
278 #endif /* NSSDEBUG */ 258 #endif /* NSSDEBUG */
279 259
280 sv = PL_strlen((const char *)s) + 1; 260 sv = PL_strlen((const char *)s) + 1;
281 #ifdef PEDANTIC 261 #ifdef PEDANTIC
282 if( '\0' != ((const char *)s)[ sv-1 ] ) { 262 if ('\0' != ((const char *)s)[sv - 1]) {
283 /* wrapped */ 263 /* wrapped */
284 nss_SetError(NSS_ERROR_VALUE_TOO_LARGE); 264 nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
285 if( (PRStatus *)NULL != statusOpt ) { 265 if ((PRStatus *)NULL != statusOpt) {
286 *statusOpt = PR_FAILURE; 266 *statusOpt = PR_FAILURE;
267 }
268 return 0;
287 } 269 }
288 return 0;
289 }
290 #endif /* PEDANTIC */ 270 #endif /* PEDANTIC */
291 271
292 if( (PRStatus *)NULL != statusOpt ) { 272 if ((PRStatus *)NULL != statusOpt) {
293 *statusOpt = PR_SUCCESS; 273 *statusOpt = PR_SUCCESS;
294 } 274 }
295 275
296 return sv; 276 return sv;
297 } 277 }
298 278
299 /* 279 /*
300 * nssUTF8_Length 280 * nssUTF8_Length
301 * 281 *
302 * This routine returns the length in characters (not including the 282 * This routine returns the length in characters (not including the
303 * terminating null) of the UTF8-encoded string pointed to by the 283 * terminating null) of the UTF8-encoded string pointed to by the
304 * specified NSSUTF8 pointer. 284 * specified NSSUTF8 pointer.
305 * 285 *
306 * The error may be one of the following values: 286 * The error may be one of the following values:
307 * NSS_ERROR_INVALID_POINTER 287 * NSS_ERROR_INVALID_POINTER
308 * NSS_ERROR_VALUE_TOO_LARGE 288 * NSS_ERROR_VALUE_TOO_LARGE
309 * NSS_ERROR_INVALID_STRING 289 * NSS_ERROR_INVALID_STRING
310 * 290 *
311 * Return value: 291 * Return value:
312 * length of the string (which may be zero) 292 * length of the string (which may be zero)
313 * 0 on error 293 * 0 on error
314 */ 294 */
315 295
316 NSS_IMPLEMENT PRUint32 296 NSS_IMPLEMENT PRUint32
317 nssUTF8_Length 297 nssUTF8_Length(const NSSUTF8 *s, PRStatus *statusOpt)
318 (
319 const NSSUTF8 *s,
320 PRStatus *statusOpt
321 )
322 { 298 {
323 PRUint32 l = 0; 299 PRUint32 l = 0;
324 const PRUint8 *c = (const PRUint8 *)s; 300 const PRUint8 *c = (const PRUint8 *)s;
325 301
326 #ifdef NSSDEBUG 302 #ifdef NSSDEBUG
327 if( (const NSSUTF8 *)NULL == s ) { 303 if ((const NSSUTF8 *)NULL == s) {
328 nss_SetError(NSS_ERROR_INVALID_POINTER); 304 nss_SetError(NSS_ERROR_INVALID_POINTER);
329 goto loser; 305 goto loser;
330 } 306 }
331 #endif /* NSSDEBUG */ 307 #endif /* NSSDEBUG */
332 308
333 /* 309 /*
334 * From RFC 2044: 310 * From RFC 2044:
335 * 311 *
336 * UCS-4 range (hex.) UTF-8 octet sequence (binary) 312 * UCS-4 range (hex.) UTF-8 octet sequence (binary)
337 * 0000 0000-0000 007F 0xxxxxxx 313 * 0000 0000-0000 007F 0xxxxxxx
338 * 0000 0080-0000 07FF 110xxxxx 10xxxxxx 314 * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
339 * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 315 * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
340 * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 316 * 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
341 * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 317 * 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
342 * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx 318 * 0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx
343 */ 319 */
344 320
345 while( 0 != *c ) { 321 while (0 != *c) {
346 PRUint32 incr; 322 PRUint32 incr;
347 if( (*c & 0x80) == 0 ) { 323 if ((*c & 0x80) == 0) {
348 incr = 1; 324 incr = 1;
349 } else if( (*c & 0xE0) == 0xC0 ) { 325 } else if ((*c & 0xE0) == 0xC0) {
350 incr = 2; 326 incr = 2;
351 } else if( (*c & 0xF0) == 0xE0 ) { 327 } else if ((*c & 0xF0) == 0xE0) {
352 incr = 3; 328 incr = 3;
353 } else if( (*c & 0xF8) == 0xF0 ) { 329 } else if ((*c & 0xF8) == 0xF0) {
354 incr = 4; 330 incr = 4;
355 } else if( (*c & 0xFC) == 0xF8 ) { 331 } else if ((*c & 0xFC) == 0xF8) {
356 incr = 5; 332 incr = 5;
357 } else if( (*c & 0xFE) == 0xFC ) { 333 } else if ((*c & 0xFE) == 0xFC) {
358 incr = 6; 334 incr = 6;
359 } else { 335 } else {
360 nss_SetError(NSS_ERROR_INVALID_STRING); 336 nss_SetError(NSS_ERROR_INVALID_STRING);
361 goto loser; 337 goto loser;
338 }
339
340 l += incr;
341
342 #ifdef PEDANTIC
343 if (l < incr) {
344 /* Wrapped-- too big */
345 nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
346 goto loser;
347 }
348
349 {
350 PRUint8 *d;
351 for (d = &c[1]; d < &c[incr]; d++) {
352 if ((*d & 0xC0) != 0xF0) {
353 nss_SetError(NSS_ERROR_INVALID_STRING);
354 goto loser;
355 }
356 }
357 }
358 #endif /* PEDANTIC */
359
360 c += incr;
362 } 361 }
363 362
364 l += incr; 363 if ((PRStatus *)NULL != statusOpt) {
365 364 *statusOpt = PR_SUCCESS;
366 #ifdef PEDANTIC
367 if( l < incr ) {
368 /* Wrapped-- too big */
369 nss_SetError(NSS_ERROR_VALUE_TOO_LARGE);
370 goto loser;
371 } 365 }
372 366
373 { 367 return l;
374 PRUint8 *d; 368
375 for( d = &c[1]; d < &c[incr]; d++ ) { 369 loser:
376 if( (*d & 0xC0) != 0xF0 ) { 370 if ((PRStatus *)NULL != statusOpt) {
377 nss_SetError(NSS_ERROR_INVALID_STRING); 371 *statusOpt = PR_FAILURE;
378 goto loser;
379 }
380 }
381 } 372 }
382 #endif /* PEDANTIC */
383 373
384 c += incr; 374 return 0;
385 }
386
387 if( (PRStatus *)NULL != statusOpt ) {
388 *statusOpt = PR_SUCCESS;
389 }
390
391 return l;
392
393 loser:
394 if( (PRStatus *)NULL != statusOpt ) {
395 *statusOpt = PR_FAILURE;
396 }
397
398 return 0;
399 } 375 }
400 376
401
402 /* 377 /*
403 * nssUTF8_Create 378 * nssUTF8_Create
404 * 379 *
405 * This routine creates a UTF8 string from a string in some other 380 * This routine creates a UTF8 string from a string in some other
406 * format. Some types of string may include embedded null characters, 381 * format. Some types of string may include embedded null characters,
407 * so for them the length parameter must be used. For string types 382 * so for them the length parameter must be used. For string types
408 * that are null-terminated, the length parameter is optional; if it 383 * that are null-terminated, the length parameter is optional; if it
409 * is zero, it will be ignored. If the optional arena argument is 384 * is zero, it will be ignored. If the optional arena argument is
410 * non-null, the memory used for the new string will be obtained from 385 * non-null, the memory used for the new string will be obtained from
411 * that arena, otherwise it will be obtained from the heap. This 386 * that arena, otherwise it will be obtained from the heap. This
412 * routine may return NULL upon error, in which case it will have 387 * routine may return NULL upon error, in which case it will have
413 * placed an error on the error stack. 388 * placed an error on the error stack.
414 * 389 *
415 * The error may be one of the following: 390 * The error may be one of the following:
416 * NSS_ERROR_INVALID_POINTER 391 * NSS_ERROR_INVALID_POINTER
417 * NSS_ERROR_NO_MEMORY 392 * NSS_ERROR_NO_MEMORY
418 * NSS_ERROR_UNSUPPORTED_TYPE 393 * NSS_ERROR_UNSUPPORTED_TYPE
419 * 394 *
420 * Return value: 395 * Return value:
421 * NULL upon error 396 * NULL upon error
422 * A non-null pointer to a new UTF8 string otherwise 397 * A non-null pointer to a new UTF8 string otherwise
423 */ 398 */
424 399
425 extern const NSSError NSS_ERROR_INTERNAL_ERROR; /* XXX fgmr */ 400 extern const NSSError NSS_ERROR_INTERNAL_ERROR; /* XXX fgmr */
426 401
427 NSS_IMPLEMENT NSSUTF8 * 402 NSS_IMPLEMENT NSSUTF8 *
428 nssUTF8_Create 403 nssUTF8_Create(NSSArena *arenaOpt, nssStringType type, const void *inputString,
429 ( 404 PRUint32 size /* in bytes, not characters */
430 NSSArena *arenaOpt, 405 )
431 nssStringType type,
432 const void *inputString,
433 PRUint32 size /* in bytes, not characters */
434 )
435 { 406 {
436 NSSUTF8 *rv = NULL; 407 NSSUTF8 *rv = NULL;
437 408
438 #ifdef NSSDEBUG 409 #ifdef NSSDEBUG
439 if( (NSSArena *)NULL != arenaOpt ) { 410 if ((NSSArena *)NULL != arenaOpt) {
440 if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { 411 if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
441 return (NSSUTF8 *)NULL; 412 return (NSSUTF8 *)NULL;
442 } 413 }
443 } 414 }
444 415
445 if( (const void *)NULL == inputString ) { 416 if ((const void *)NULL == inputString) {
446 nss_SetError(NSS_ERROR_INVALID_POINTER); 417 nss_SetError(NSS_ERROR_INVALID_POINTER);
447 return (NSSUTF8 *)NULL; 418 return (NSSUTF8 *)NULL;
448 } 419 }
449 #endif /* NSSDEBUG */ 420 #endif /* NSSDEBUG */
450 421
451 switch( type ) { 422 switch (type) {
452 case nssStringType_DirectoryString: 423 case nssStringType_DirectoryString:
453 /* This is a composite type requiring BER */ 424 /* This is a composite type requiring BER */
454 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); 425 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
455 break; 426 break;
456 case nssStringType_TeletexString: 427 case nssStringType_TeletexString:
457 /* 428 /*
458 * draft-ietf-pkix-ipki-part1-11 says in part: 429 * draft-ietf-pkix-ipki-part1-11 says in part:
459 * 430 *
460 * In addition, many legacy implementations support names encoded 431 * In addition, many legacy implementations support names encoded
461 * in the ISO 8859-1 character set (Latin1String) but tag them as 432 * in the ISO 8859-1 character set (Latin1String) but tag them as
462 * TeletexString. The Latin1String includes characters used in 433 * TeletexString. The Latin1String includes characters used in
463 * Western European countries which are not part of the 434 * Western European countries which are not part of the
464 * TeletexString charcter set. Implementations that process 435 * TeletexString charcter set. Implementations that process
465 * TeletexString SHOULD be prepared to handle the entire ISO 436 * TeletexString SHOULD be prepared to handle the entire ISO
466 * 8859-1 character set.[ISO 8859-1]. 437 * 8859-1 character set.[ISO 8859-1].
467 */ 438 */
468 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 439 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
469 break; 440 break;
470 case nssStringType_PrintableString: 441 case nssStringType_PrintableString:
471 /* 442 /*
472 * PrintableString consists of A-Za-z0-9 ,()+,-./:=? 443 * PrintableString consists of A-Za-z0-9 ,()+,-./:=?
473 * This is a subset of ASCII, which is a subset of UTF8. 444 * This is a subset of ASCII, which is a subset of UTF8.
474 * So we can just duplicate the string over. 445 * So we can just duplicate the string over.
475 */ 446 */
476 447
477 if( 0 == size ) { 448 if (0 == size) {
478 rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt); 449 rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);
479 } else { 450 } else {
480 rv = nss_ZAlloc(arenaOpt, size+1); 451 rv = nss_ZAlloc(arenaOpt, size + 1);
481 if( (NSSUTF8 *)NULL == rv ) { 452 if ((NSSUTF8 *)NULL == rv) {
482 return (NSSUTF8 *)NULL; 453 return (NSSUTF8 *)NULL;
483 } 454 }
484 455
485 (void)nsslibc_memcpy(rv, inputString, size); 456 (void)nsslibc_memcpy(rv, inputString, size);
486 } 457 }
487 458
488 break; 459 break;
489 case nssStringType_UniversalString: 460 case nssStringType_UniversalString:
490 /* 4-byte unicode */ 461 /* 4-byte unicode */
491 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 462 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
492 break; 463 break;
493 case nssStringType_BMPString: 464 case nssStringType_BMPString:
494 /* Base Multilingual Plane of Unicode */ 465 /* Base Multilingual Plane of Unicode */
495 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 466 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
496 break; 467 break;
497 case nssStringType_UTF8String: 468 case nssStringType_UTF8String:
498 if( 0 == size ) { 469 if (0 == size) {
499 rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt); 470 rv = nssUTF8_Duplicate((const NSSUTF8 *)inputString, arenaOpt);
500 } else { 471 } else {
501 rv = nss_ZAlloc(arenaOpt, size+1); 472 rv = nss_ZAlloc(arenaOpt, size + 1);
502 if( (NSSUTF8 *)NULL == rv ) { 473 if ((NSSUTF8 *)NULL == rv) {
503 return (NSSUTF8 *)NULL; 474 return (NSSUTF8 *)NULL;
504 } 475 }
505 476
506 (void)nsslibc_memcpy(rv, inputString, size); 477 (void)nsslibc_memcpy(rv, inputString, size);
507 } 478 }
508 479
509 break; 480 break;
510 case nssStringType_PHGString: 481 case nssStringType_PHGString:
511 /* 482 /*
512 * PHGString is an IA5String (with case-insensitive comparisons). 483 * PHGString is an IA5String (with case-insensitive comparisons).
513 * IA5 is ~almost~ ascii; ascii has dollar-sign where IA5 has 484 * IA5 is ~almost~ ascii; ascii has dollar-sign where IA5 has
514 * currency symbol. 485 * currency symbol.
515 */ 486 */
516 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 487 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
517 break; 488 break;
518 case nssStringType_GeneralString: 489 case nssStringType_GeneralString:
519 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 490 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
520 break; 491 break;
521 default: 492 default:
522 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); 493 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
523 break; 494 break;
524 } 495 }
525 496
526 return rv; 497 return rv;
527 } 498 }
528 499
529 NSS_IMPLEMENT NSSItem * 500 NSS_IMPLEMENT NSSItem *
530 nssUTF8_GetEncoding 501 nssUTF8_GetEncoding(NSSArena *arenaOpt, NSSItem *rvOpt, nssStringType type,
531 ( 502 NSSUTF8 *string)
532 NSSArena *arenaOpt,
533 NSSItem *rvOpt,
534 nssStringType type,
535 NSSUTF8 *string
536 )
537 { 503 {
538 NSSItem *rv = (NSSItem *)NULL; 504 NSSItem *rv = (NSSItem *)NULL;
539 PRStatus status = PR_SUCCESS; 505 PRStatus status = PR_SUCCESS;
540 506
541 #ifdef NSSDEBUG 507 #ifdef NSSDEBUG
542 if( (NSSArena *)NULL != arenaOpt ) { 508 if ((NSSArena *)NULL != arenaOpt) {
543 if( PR_SUCCESS != nssArena_verifyPointer(arenaOpt) ) { 509 if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) {
544 return (NSSItem *)NULL; 510 return (NSSItem *)NULL;
545 } 511 }
546 } 512 }
547 513
548 if( (NSSUTF8 *)NULL == string ) { 514 if ((NSSUTF8 *)NULL == string) {
549 nss_SetError(NSS_ERROR_INVALID_POINTER); 515 nss_SetError(NSS_ERROR_INVALID_POINTER);
550 return (NSSItem *)NULL; 516 return (NSSItem *)NULL;
551 } 517 }
552 #endif /* NSSDEBUG */ 518 #endif /* NSSDEBUG */
553 519
554 switch( type ) { 520 switch (type) {
555 case nssStringType_DirectoryString: 521 case nssStringType_DirectoryString:
556 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 522 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
557 break; 523 break;
558 case nssStringType_TeletexString: 524 case nssStringType_TeletexString:
559 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 525 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
560 break; 526 break;
561 case nssStringType_PrintableString: 527 case nssStringType_PrintableString:
562 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 528 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
563 break; 529 break;
564 case nssStringType_UniversalString: 530 case nssStringType_UniversalString:
565 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 531 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
566 break; 532 break;
567 case nssStringType_BMPString: 533 case nssStringType_BMPString:
568 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 534 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
569 break; 535 break;
570 case nssStringType_UTF8String: 536 case nssStringType_UTF8String: {
571 { 537 NSSUTF8 *dup = nssUTF8_Duplicate(string, arenaOpt);
572 NSSUTF8 *dup = nssUTF8_Duplicate(string, arenaOpt); 538 if ((NSSUTF8 *)NULL == dup) {
573 if( (NSSUTF8 *)NULL == dup ) { 539 return (NSSItem *)NULL;
574 return (NSSItem *)NULL; 540 }
575 } 541
576 542 if ((NSSItem *)NULL == rvOpt) {
577 if( (NSSItem *)NULL == rvOpt ) { 543 rv = nss_ZNEW(arenaOpt, NSSItem);
578 rv = nss_ZNEW(arenaOpt, NSSItem); 544 if ((NSSItem *)NULL == rv) {
579 if( (NSSItem *)NULL == rv ) { 545 (void)nss_ZFreeIf(dup);
580 (void)nss_ZFreeIf(dup); 546 return (NSSItem *)NULL;
581 return (NSSItem *)NULL; 547 }
582 } 548 } else {
583 } else { 549 rv = rvOpt;
584 rv = rvOpt; 550 }
585 } 551
586 552 rv->data = dup;
587 rv->data = dup; 553 dup = (NSSUTF8 *)NULL;
588 dup = (NSSUTF8 *)NULL; 554 rv->size = nssUTF8_Size(rv->data, &status);
589 rv->size = nssUTF8_Size(rv->data, &status); 555 if ((0 == rv->size) && (PR_SUCCESS != status)) {
590 if( (0 == rv->size) && (PR_SUCCESS != status) ) { 556 if ((NSSItem *)NULL == rvOpt) {
591 if( (NSSItem *)NULL == rvOpt ) { 557 (void)nss_ZFreeIf(rv);
592 (void)nss_ZFreeIf(rv); 558 }
593 } 559 return (NSSItem *)NULL;
594 return (NSSItem *)NULL; 560 }
595 } 561 } break;
596 } 562 case nssStringType_PHGString:
597 break; 563 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */
598 case nssStringType_PHGString: 564 break;
599 nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ 565 default:
600 break; 566 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE);
601 default: 567 break;
602 nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); 568 }
603 break; 569
604 } 570 return rv;
605
606 return rv;
607 } 571 }
608 572
609 /* 573 /*
610 * nssUTF8_CopyIntoFixedBuffer 574 * nssUTF8_CopyIntoFixedBuffer
611 * 575 *
612 * This will copy a UTF8 string into a fixed-length buffer, making 576 * This will copy a UTF8 string into a fixed-length buffer, making
613 * sure that the all characters are valid. Any remaining space will 577 * sure that the all characters are valid. Any remaining space will
614 * be padded with the specified ASCII character, typically either 578 * be padded with the specified ASCII character, typically either
615 * null or space. 579 * null or space.
616 * 580 *
617 * Blah, blah, blah. 581 * Blah, blah, blah.
618 */ 582 */
619 583
620 NSS_IMPLEMENT PRStatus 584 NSS_IMPLEMENT PRStatus
621 nssUTF8_CopyIntoFixedBuffer 585 nssUTF8_CopyIntoFixedBuffer(NSSUTF8 *string, char *buffer, PRUint32 bufferSize,
622 ( 586 char pad)
623 NSSUTF8 *string,
624 char *buffer,
625 PRUint32 bufferSize,
626 char pad
627 )
628 { 587 {
629 PRUint32 stringSize = 0; 588 PRUint32 stringSize = 0;
630 589
631 #ifdef NSSDEBUG 590 #ifdef NSSDEBUG
632 if( (char *)NULL == buffer ) { 591 if ((char *)NULL == buffer) {
633 nss_SetError(NSS_ERROR_INVALID_POINTER); 592 nss_SetError(NSS_ERROR_INVALID_POINTER);
634 return PR_FALSE; 593 return PR_FALSE;
635 } 594 }
636 595
637 if( 0 == bufferSize ) { 596 if (0 == bufferSize) {
638 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); 597 nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
639 return PR_FALSE; 598 return PR_FALSE;
640 } 599 }
641 600
642 if( (pad & 0x80) != 0x00 ) { 601 if ((pad & 0x80) != 0x00) {
643 nss_SetError(NSS_ERROR_INVALID_ARGUMENT); 602 nss_SetError(NSS_ERROR_INVALID_ARGUMENT);
644 return PR_FALSE; 603 return PR_FALSE;
645 } 604 }
646 #endif /* NSSDEBUG */ 605 #endif /* NSSDEBUG */
647 606
648 if( (NSSUTF8 *)NULL == string ) { 607 if ((NSSUTF8 *)NULL == string) {
649 string = (NSSUTF8 *) ""; 608 string = (NSSUTF8 *)"";
650 } 609 }
651 610
652 stringSize = nssUTF8_Size(string, (PRStatus *)NULL); 611 stringSize = nssUTF8_Size(string, (PRStatus *)NULL);
653 stringSize--; /* don't count the trailing null */ 612 stringSize--; /* don't count the trailing null */
654 if( stringSize > bufferSize ) { 613 if (stringSize > bufferSize) {
655 PRUint32 bs = bufferSize; 614 PRUint32 bs = bufferSize;
656 (void)nsslibc_memcpy(buffer, string, bufferSize); 615 (void)nsslibc_memcpy(buffer, string, bufferSize);
657 616
658 if( ( ((buffer[ bs-1 ] & 0x80) == 0x00)) || 617 if (( ((buffer[bs - 1] & 0x80) == 0x00)) ||
659 ((bs > 1) && ((buffer[ bs-2 ] & 0xE0) == 0xC0)) || 618 ((bs > 1) && ((buffer[bs - 2] & 0xE0) == 0xC0)) ||
660 ((bs > 2) && ((buffer[ bs-3 ] & 0xF0) == 0xE0)) || 619 ((bs > 2) && ((buffer[bs - 3] & 0xF0) == 0xE0)) ||
661 ((bs > 3) && ((buffer[ bs-4 ] & 0xF8) == 0xF0)) || 620 ((bs > 3) && ((buffer[bs - 4] & 0xF8) == 0xF0)) ||
662 ((bs > 4) && ((buffer[ bs-5 ] & 0xFC) == 0xF8)) || 621 ((bs > 4) && ((buffer[bs - 5] & 0xFC) == 0xF8)) ||
663 ((bs > 5) && ((buffer[ bs-6 ] & 0xFE) == 0xFC)) ) { 622 ((bs > 5) && ((buffer[bs - 6] & 0xFE) == 0xFC))) {
664 /* It fit exactly */ 623 /* It fit exactly */
665 return PR_SUCCESS; 624 return PR_SUCCESS;
666 } 625 }
667 626
668 /* Too long. We have to trim the last character */ 627 /* Too long. We have to trim the last character */
669 for( /*bs*/; bs != 0; bs-- ) { 628 for (/*bs*/; bs != 0; bs--) {
670 if( (buffer[bs-1] & 0xC0) != 0x80 ) { 629 if ((buffer[bs - 1] & 0xC0) != 0x80) {
671 buffer[bs-1] = pad; 630 buffer[bs - 1] = pad;
672 break; 631 break;
673 } else { 632 } else {
674 buffer[bs-1] = pad; 633 buffer[bs - 1] = pad;
675 } 634 }
676 } 635 }
677 } else { 636 } else {
678 (void)nsslibc_memset(buffer, pad, bufferSize); 637 (void)nsslibc_memset(buffer, pad, bufferSize);
679 (void)nsslibc_memcpy(buffer, string, stringSize); 638 (void)nsslibc_memcpy(buffer, string, stringSize);
680 } 639 }
681 640
682 return PR_SUCCESS; 641 return PR_SUCCESS;
683 } 642 }
684 643
685 /* 644 /*
686 * nssUTF8_Equal 645 * nssUTF8_Equal
687 * 646 *
688 */ 647 */
689 648
690 NSS_IMPLEMENT PRBool 649 NSS_IMPLEMENT PRBool
691 nssUTF8_Equal 650 nssUTF8_Equal(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt)
692 (
693 const NSSUTF8 *a,
694 const NSSUTF8 *b,
695 PRStatus *statusOpt
696 )
697 { 651 {
698 PRUint32 la, lb; 652 PRUint32 la, lb;
699 653
700 #ifdef NSSDEBUG 654 #ifdef NSSDEBUG
701 if( ((const NSSUTF8 *)NULL == a) || 655 if (((const NSSUTF8 *)NULL == a) || ((const NSSUTF8 *)NULL == b)) {
702 ((const NSSUTF8 *)NULL == b) ) { 656 nss_SetError(NSS_ERROR_INVALID_POINTER);
703 nss_SetError(NSS_ERROR_INVALID_POINTER); 657 if ((PRStatus *)NULL != statusOpt) {
704 if( (PRStatus *)NULL != statusOpt ) { 658 *statusOpt = PR_FAILURE;
705 *statusOpt = PR_FAILURE; 659 }
660 return PR_FALSE;
706 } 661 }
707 return PR_FALSE;
708 }
709 #endif /* NSSDEBUG */ 662 #endif /* NSSDEBUG */
710 663
711 la = nssUTF8_Size(a, statusOpt); 664 la = nssUTF8_Size(a, statusOpt);
712 if( 0 == la ) { 665 if (0 == la) {
713 return PR_FALSE; 666 return PR_FALSE;
714 } 667 }
715 668
716 lb = nssUTF8_Size(b, statusOpt); 669 lb = nssUTF8_Size(b, statusOpt);
717 if( 0 == lb ) { 670 if (0 == lb) {
718 return PR_FALSE; 671 return PR_FALSE;
719 } 672 }
720 673
721 if( la != lb ) { 674 if (la != lb) {
722 return PR_FALSE; 675 return PR_FALSE;
723 } 676 }
724 677
725 return nsslibc_memequal(a, b, la, statusOpt); 678 return nsslibc_memequal(a, b, la, statusOpt);
726 } 679 }
OLDNEW
« no previous file with comments | « nss/lib/base/nssbaset.h ('k') | nss/lib/base/tracker.c » ('j') | nss/lib/util/secoid.c » ('J')

Powered by Google App Engine
This is Rietveld 408576698