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  * test_string.c
6  *
7  * Tests Strings.
8  *
9  */
10 
11 #include "testutil.h"
12 #include "testutil_nss.h"
13 
14 static void *plContext = NULL;
15 
16 static void
createString(PKIX_PL_String ** testString,PKIX_UInt32 format,char * stringAscii,PKIX_UInt32 length)17 createString(
18     PKIX_PL_String **testString,
19     PKIX_UInt32 format,
20     char *stringAscii,
21     PKIX_UInt32 length)
22 {
23     PKIX_TEST_STD_VARS();
24 
25     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(format, stringAscii, length, testString, plContext));
26 
27 cleanup:
28 
29     PKIX_TEST_RETURN();
30 }
31 
32 static void
createStringOther(PKIX_PL_String ** testEscAscii,PKIX_PL_String ** testUtf16,PKIX_PL_String ** ampString,PKIX_PL_String ** testDebugAscii,PKIX_PL_String ** testNullString,PKIX_UInt32 * utf16data)33 createStringOther(
34     PKIX_PL_String **testEscAscii,
35     PKIX_PL_String **testUtf16,
36     PKIX_PL_String **ampString,
37     PKIX_PL_String **testDebugAscii,
38     PKIX_PL_String **testNullString,
39     PKIX_UInt32 *utf16data)
40 {
41     char *nullText = "Hi� there!";
42 
43     char *escAsciiString =
44         "¡𐀀࿿􀀁";
45 
46     char *debugAsciiString =
47         "string with
newlines and	tabs";
48 
49     char *utfAmp = "\x00&";
50 
51     PKIX_TEST_STD_VARS();
52 
53     createString(testEscAscii,
54                  PKIX_ESCASCII,
55                  escAsciiString,
56                  PL_strlen(escAsciiString));
57 
58     createString(testUtf16, PKIX_UTF16, (char *)utf16data, 12);
59 
60     createString(ampString, PKIX_UTF16, utfAmp, 2);
61 
62     createString(testDebugAscii,
63                  PKIX_ESCASCII_DEBUG,
64                  debugAsciiString,
65                  PL_strlen(debugAsciiString));
66 
67     createString(testNullString,
68                  PKIX_ESCASCII_DEBUG,
69                  nullText,
70                  PL_strlen(nullText));
71 
72     goto cleanup;
73 
74 cleanup:
75 
76     PKIX_TEST_RETURN();
77 }
78 
79 static void
testGetEncoded(PKIX_PL_String * testEscAscii,PKIX_PL_String * testString0,PKIX_PL_String * testDebugAscii,PKIX_PL_String * testNullString,PKIX_UInt32 * utf16data)80 testGetEncoded(
81     PKIX_PL_String *testEscAscii,
82     PKIX_PL_String *testString0,
83     PKIX_PL_String *testDebugAscii,
84     PKIX_PL_String *testNullString,
85     PKIX_UInt32 *utf16data)
86 {
87     char *temp = NULL;
88     void *dest = NULL;
89     void *dest2 = NULL;
90     char *plainText = "string with\nnewlines and\ttabs";
91     PKIX_UInt32 length, length2, i;
92 
93     PKIX_TEST_STD_VARS();
94 
95     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testEscAscii,
96                                                         PKIX_UTF16,
97                                                         &dest,
98                                                         &length,
99                                                         plContext));
100     for (i = 0; i < length; i++) {
101         if (((char *)dest)[i] != ((char *)utf16data)[i]) {
102             testError("UTF-16 Data Differs from Source");
103             printf("%d-th char is different -%c-%c-\n", i,
104                    ((char *)dest)[i], ((char *)utf16data)[i]);
105         }
106     }
107 
108     length = 0;
109     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext));
110 
111     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testNullString,
112                                                         PKIX_UTF16,
113                                                         &dest,
114                                                         &length,
115                                                         plContext));
116 
117     length = 0;
118     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext));
119 
120     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testString0,
121                                                         PKIX_ESCASCII_DEBUG,
122                                                         &dest,
123                                                         &length,
124                                                         plContext));
125 
126     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_GetEncoded(testDebugAscii,
127                                                         PKIX_ESCASCII_DEBUG,
128                                                         &dest2,
129                                                         &length2,
130                                                         plContext));
131 
132     for (i = 0; (i < length) && (i < length2); i++)
133         if (((char *)dest)[i] != ((char *)dest2)[i]) {
134             testError("Equivalent strings are unequal");
135             break;
136         }
137 
138     length = 0;
139     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest, plContext));
140     length2 = 0;
141     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(dest2, plContext));
142 
143     temp = PKIX_String2ASCII(testDebugAscii, plContext);
144     if (temp) {
145         if (PL_strcmp(plainText, temp) != 0)
146             testError("Debugged ASCII does not match "
147                       "equivalent EscAscii");
148         PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
149     }
150 
151 cleanup:
152 
153     PKIX_TEST_RETURN();
154 }
155 
156 static void
testSprintf(void)157 testSprintf(void)
158 {
159     PKIX_Int32 x = 0xCAFE;
160     PKIX_Int32 y = -12345;
161     PKIX_PL_String *testString = NULL;
162     PKIX_PL_String *formatString = NULL;
163     PKIX_PL_String *sprintfString = NULL;
164     char *plainText = "Testing Sprintf";
165     char *format = "%s %x %u %d";
166     char *convertedFormat = "%s %lx %lu %ld";
167     char *temp = NULL;
168     char *temp2 = NULL;
169 
170     PKIX_TEST_STD_VARS();
171 
172     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(
173         PKIX_ESCASCII,
174         plainText,
175         PL_strlen(plainText),
176         &testString,
177         plContext));
178 
179     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create(
180         PKIX_ESCASCII,
181         format,
182         11,
183         &formatString,
184         plContext));
185 
186     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Sprintf(&sprintfString,
187                                               plContext,
188                                               formatString,
189                                               testString, x, y, y));
190     PKIX_TEST_DECREF_BC(testString);
191 
192     temp = PR_smprintf(convertedFormat, plainText, x, y, y);
193     temp2 = PKIX_String2ASCII(sprintfString, plContext);
194 
195     if (PL_strcmp(temp, temp2) != 0)
196         testError("Sprintf produced incorrect output");
197 
198     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
199     PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp2, plContext));
200 
201     PKIX_TEST_DECREF_BC(sprintfString);
202 
203     PKIX_TEST_DECREF_BC(formatString);
204 
205 cleanup:
206 
207     PKIX_TEST_RETURN();
208 }
209 
210 static void
testErrorHandling(void)211 testErrorHandling(void)
212 {
213     char *debugAsciiString =
214         "string with&#x000A;newlines and&#x0009;tabs";
215 
216     PKIX_PL_String *testString = NULL;
217 
218     PKIX_TEST_STD_VARS();
219 
220     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
221         PKIX_ESCASCII,
222         NULL,
223         50,
224         &testString,
225         plContext));
226 
227     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(PKIX_ESCASCII,
228                                                  "blah", 4, NULL, plContext));
229 
230     PKIX_TEST_EXPECT_ERROR(PKIX_PL_Sprintf(&testString, plContext, NULL));
231 
232     PKIX_TEST_EXPECT_ERROR(PKIX_PL_GetString(0, NULL, &testString, plContext));
233 
234     PKIX_TEST_EXPECT_ERROR(PKIX_PL_GetString(0, "blah", 0, plContext));
235 
236     /* ---------------------------- */
237     subTest("Unicode Error Handling");
238 
239     /* &#x must be followed by 4 hexadecimal digits */
240     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
241         PKIX_ESCASCII,
242         "&#x003k;",
243         7,
244         &testString,
245         plContext));
246 
247     /* &#x must be followed by 4 hexadecimal digits */
248     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
249         PKIX_ESCASCII,
250         "abc&#x00",
251         8,
252         &testString,
253         plContext));
254 
255     /* &#x must be between 00010000-0010FFFF */
256     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
257         PKIX_ESCASCII,
258         "&#x00200101;",
259         11,
260         &testString,
261         plContext));
262 
263     /* &#x must be followed by 8 hexadecimal digits */
264     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
265         PKIX_ESCASCII,
266         "&#x001000",
267         10,
268         &testString,
269         plContext));
270 
271     /* &#x must be followed by 8 hexadecimal digits */
272     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
273         PKIX_ESCASCII,
274         "&#x0010m00;",
275         10,
276         &testString,
277         plContext));
278 
279     /* Byte values D800-DFFF are reserved */
280     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
281         PKIX_ESCASCII,
282         "&#xD800;",
283         7,
284         &testString,
285         plContext));
286 
287     /* Can't use &#x for regular characters */
288     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
289         PKIX_ESCASCII,
290         "&#x0032;",
291         7,
292         &testString,
293         plContext));
294 
295     /* Can't use non-printable characters */
296     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
297         PKIX_ESCASCII,
298         "\xA1",
299         1,
300         &testString,
301         plContext));
302 
303     /* Only legal \\ characters are \\, u and U */
304     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
305         PKIX_ESCASCII,
306         "&blah",
307         5,
308         &testString,
309         plContext));
310 
311     /* Surrogate pairs must be legal */
312     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
313         PKIX_UTF16,
314         "\xd8\x00\x0\x66",
315         4,
316         &testString,
317         plContext));
318 
319     /* Debugged EscASCII should not be accepted as EscASCII */
320     PKIX_TEST_EXPECT_ERROR(PKIX_PL_String_Create(
321         PKIX_ESCASCII,
322         debugAsciiString,
323         PL_strlen(debugAsciiString),
324         &testString,
325         plContext));
326 cleanup:
327 
328     PKIX_TEST_RETURN();
329 }
330 
331 static void
testDestroy(PKIX_PL_String * string)332 testDestroy(
333     PKIX_PL_String *string)
334 {
335     PKIX_TEST_STD_VARS();
336 
337     PKIX_TEST_DECREF_BC(string);
338 
339 cleanup:
340 
341     PKIX_TEST_RETURN();
342 }
343 
344 int
test_string(int argc,char * argv[])345 test_string(int argc, char *argv[])
346 {
347 
348     PKIX_PL_String *testString[6] = { NULL };
349     PKIX_PL_String *testNullString = NULL;
350     PKIX_PL_String *testDebugAscii = NULL;
351     PKIX_PL_String *testEscAscii = NULL;
352     PKIX_PL_String *testUtf16 = NULL;
353     PKIX_PL_String *ampString = NULL;
354     unsigned char utf16Data[] = { 0x00, 0xA1, 0xD8, 0x00,
355                                   0xDC, 0x00, 0x0F, 0xFF,
356                                   0xDB, 0xC0, 0xDC, 0x01 };
357     PKIX_UInt32 i, size = 6;
358 
359     char *plainText[6] = {
360         "string with\nnewlines and\ttabs",
361         "Not an escaped char: &amp;#x0012;",
362         "Encode &amp; with &amp;amp; in ASCII",
363         "&#x00A1;",
364         "&amp;",
365         "string with\nnewlines and\ttabs"
366     };
367 
368     PKIX_UInt32 actualMinorVersion;
369     PKIX_UInt32 j = 0;
370 
371     PKIX_TEST_STD_VARS();
372 
373     startTests("Strings");
374 
375     PKIX_TEST_EXPECT_NO_ERROR(
376         PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));
377 
378     subTest("PKIX_PL_String_Create <ascii format>");
379     for (i = 0; i < size; i++) {
380         testString[i] = NULL;
381         createString(&testString[i],
382                      PKIX_ESCASCII,
383                      plainText[i],
384                      PL_strlen(plainText[i]));
385     }
386 
387     subTest("PKIX_PL_String_Create <other formats>");
388     createStringOther(&testEscAscii,
389                       &testUtf16,
390                       &ampString,
391                       &testDebugAscii,
392                       &testNullString,
393                       (PKIX_UInt32 *)utf16Data);
394 
395     PKIX_TEST_EQ_HASH_TOSTR_DUP(testString[0],
396                                 testString[5],
397                                 testString[1],
398                                 plainText[0],
399                                 String,
400                                 PKIX_TRUE);
401 
402     subTest("PKIX_PL_String_GetEncoded");
403     testGetEncoded(testEscAscii,
404                    testString[0],
405                    testDebugAscii,
406                    testNullString,
407                    (PKIX_UInt32 *)utf16Data);
408 
409     subTest("PKIX_PL_Sprintf");
410     testSprintf();
411 
412     subTest("PKIX_PL_String_Create <error_handling>");
413     testErrorHandling();
414 
415     subTest("PKIX_PL_String_Destroy");
416     for (i = 0; i < size; i++) {
417         testDestroy(testString[i]);
418     }
419     testDestroy(testEscAscii);
420     testDestroy(testUtf16);
421     testDestroy(ampString);
422     testDestroy(testDebugAscii);
423     testDestroy(testNullString);
424 
425 cleanup:
426 
427     PKIX_Shutdown(plContext);
428 
429     PKIX_TEST_RETURN();
430 
431     endTests("String");
432 
433     return (0);
434 }
435