Coverage Report

Created: 2018-09-25 14:53

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