| 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 |