OLD | NEW |
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 } |
OLD | NEW |