1 /*
2  *******************************************************************************
3  *
4  *   Copyright (C) 2003-2014, International Business Machines
5  *   Corporation and others.  All Rights Reserved.
6  *
7  *******************************************************************************
8  *   file name:  spreptst.c
9  *   encoding:   US-ASCII
10  *   tab size:   8 (not used)
11  *   indentation:4
12  *
13  *   created on: 2003jul11
14  *   created by: Ram Viswanadha
15  */
16 #include <stdlib.h>
17 #include <string.h>
18 #include "unicode/utypes.h"
19 
20 #if !UCONFIG_NO_IDNA
21 
22 #include "unicode/ustring.h"
23 #include "unicode/usprep.h"
24 #include "cstring.h"
25 #include "cintltst.h"
26 #include "nfsprep.h"
27 
28 void addUStringPrepTest(TestNode** root);
29 void doStringPrepTest(const char* binFileName, const char* txtFileName,
30                  int32_t options, UErrorCode* errorCode);
31 
32 static void Test_nfs4_cs_prep_data(void);
33 static void Test_nfs4_cis_prep_data(void);
34 static void Test_nfs4_mixed_prep_data(void);
35 static void Test_nfs4_cs_prep(void);
36 static void Test_nfs4_cis_prep(void);
37 static void Test_nfs4_mixed_prep(void);
38 static void TestBEAMWarning(void);
39 static void TestCoverage(void);
40 static void TestStringPrepProfiles(void);
41 
42 UStringPrepProfileType getTypeFromProfileName(const char* profileName);
43 
44 void
addUStringPrepTest(TestNode ** root)45 addUStringPrepTest(TestNode** root)
46 {
47 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
48    addTest(root, &Test_nfs4_cs_prep_data,    "spreptst/Test_nfs4_cs_prep_data");
49    addTest(root, &Test_nfs4_cis_prep_data,   "spreptst/Test_nfs4_cis_prep_data");
50    addTest(root, &Test_nfs4_mixed_prep_data, "spreptst/Test_nfs4_mixed_prep_data");
51    addTest(root, &Test_nfs4_cs_prep,         "spreptst/Test_nfs4_cs_prep");
52    addTest(root, &Test_nfs4_cis_prep,        "spreptst/Test_nfs4_cis_prep");
53    addTest(root, &Test_nfs4_mixed_prep,      "spreptst/Test_nfs4_mixed_prep");
54    addTest(root, &TestBEAMWarning,           "spreptst/TestBEAMWarning");
55 #endif
56    addTest(root, &TestCoverage,              "spreptst/TestCoverage");
57    addTest(root, &TestStringPrepProfiles,              "spreptst/TestStringPrepProfiles");
58 }
59 
60 static void
Test_nfs4_cs_prep_data(void)61 Test_nfs4_cs_prep_data(void){
62     UErrorCode errorCode = U_ZERO_ERROR;
63     loadTestData(&errorCode);
64     if(U_FAILURE(errorCode)) {
65         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode));
66         return;
67     }
68 
69     log_verbose("Testing nfs4_cs_prep_ci.txt\n");
70     doStringPrepTest("nfscsi","nfs4_cs_prep_ci.txt", USPREP_DEFAULT, &errorCode);
71 
72     log_verbose("Testing nfs4_cs_prep_cs.txt\n");
73     errorCode = U_ZERO_ERROR;
74     doStringPrepTest("nfscss","nfs4_cs_prep_cs.txt", USPREP_DEFAULT, &errorCode);
75 
76 
77 }
78 static void
Test_nfs4_cis_prep_data(void)79 Test_nfs4_cis_prep_data(void){
80     UErrorCode errorCode = U_ZERO_ERROR;
81     log_verbose("Testing nfs4_cis_prep.txt\n");
82     doStringPrepTest("nfscis","nfs4_cis_prep.txt", USPREP_DEFAULT, &errorCode);
83 }
84 static void
Test_nfs4_mixed_prep_data(void)85 Test_nfs4_mixed_prep_data(void){
86     UErrorCode errorCode = U_ZERO_ERROR;
87     loadTestData(&errorCode);
88     if(U_FAILURE(errorCode)) {
89         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode));
90         return;
91     }
92 
93     log_verbose("Testing nfs4_mixed_prep_s.txt\n");
94     doStringPrepTest("nfsmxs","nfs4_mixed_prep_s.txt", USPREP_DEFAULT, &errorCode);
95 
96     errorCode = U_ZERO_ERROR;
97     log_verbose("Testing nfs4_mixed_prep_p.txt\n");
98     doStringPrepTest("nfsmxp","nfs4_mixed_prep_p.txt", USPREP_DEFAULT, &errorCode);
99 
100 }
101 
102 static const struct ConformanceTestCases
103    {
104      const char *comment;
105      const char *in;
106      const char *out;
107      const char *profile;
108      UErrorCode expectedStatus;
109    }
110    conformanceTestCases[] =
111    {
112 
113      {/*0*/
114        "Case folding ASCII U+0043 U+0041 U+0046 U+0045",
115        "\x43\x41\x46\x45", "\x63\x61\x66\x65",
116        "nfs4_cis_prep",
117        U_ZERO_ERROR
118 
119      },
120      {/*1*/
121        "Case folding 8bit U+00DF (german sharp s)",
122        "\xC3\x9F", "\x73\x73",
123        "nfs4_cis_prep",
124        U_ZERO_ERROR
125      },
126      {/*2*/
127        "Non-ASCII multibyte space character U+1680",
128        "\xE1\x9A\x80", NULL,
129        "nfs4_cis_prep",
130        U_STRINGPREP_PROHIBITED_ERROR
131      },
132      {/*3*/
133        "Non-ASCII 8bit control character U+0085",
134        "\xC2\x85", NULL,
135        "nfs4_cis_prep",
136        U_STRINGPREP_PROHIBITED_ERROR
137      },
138      {/*4*/
139        "Non-ASCII multibyte control character U+180E",
140        "\xE1\xA0\x8E", NULL,
141        "nfs4_cis_prep",
142        U_STRINGPREP_PROHIBITED_ERROR
143      },
144      {/*5*/
145        "Non-ASCII control character U+1D175",
146        "\xF0\x9D\x85\xB5", NULL,
147        "nfs4_cis_prep",
148        U_STRINGPREP_PROHIBITED_ERROR
149      },
150      {/*6*/
151        "Plane 0 private use character U+F123",
152        "\xEF\x84\xA3", NULL,
153        "nfs4_cis_prep",
154        U_STRINGPREP_PROHIBITED_ERROR
155      },
156      {/*7*/
157        "Plane 15 private use character U+F1234",
158        "\xF3\xB1\x88\xB4", NULL,
159        "nfs4_cis_prep",
160        U_STRINGPREP_PROHIBITED_ERROR
161      },
162      {/*8*/
163        "Plane 16 private use character U+10F234",
164        "\xF4\x8F\x88\xB4", NULL,
165        "nfs4_cis_prep",
166        U_STRINGPREP_PROHIBITED_ERROR
167      },
168      {/*9*/
169        "Non-character code point U+8FFFE",
170        "\xF2\x8F\xBF\xBE", NULL,
171        "nfs4_cis_prep",
172        U_STRINGPREP_PROHIBITED_ERROR
173      },
174      {/*10*/
175        "Non-character code point U+10FFFF",
176        "\xF4\x8F\xBF\xBF", NULL,
177        "nfs4_cis_prep",
178        U_STRINGPREP_PROHIBITED_ERROR
179      },
180  /*
181      {
182        "Surrogate code U+DF42",
183        "\xED\xBD\x82", NULL, "nfs4_cis_prep", UIDNA_DEFAULT,
184        U_STRINGPREP_PROHIBITED_ERROR
185      },
186 */
187      {/*11*/
188        "Non-plain text character U+FFFD",
189        "\xEF\xBF\xBD", NULL,
190        "nfs4_cis_prep",
191        U_STRINGPREP_PROHIBITED_ERROR
192      },
193      {/*12*/
194        "Ideographic description character U+2FF5",
195        "\xE2\xBF\xB5", NULL,
196        "nfs4_cis_prep",
197        U_STRINGPREP_PROHIBITED_ERROR
198      },
199      {/*13*/
200        "Display property character U+0341",
201        "\xCD\x81", "\xCC\x81",
202        "nfs4_cis_prep", U_ZERO_ERROR
203 
204      },
205 
206      {/*14*/
207        "Left-to-right mark U+200E",
208        "\xE2\x80\x8E", "\xCC\x81",
209        "nfs4_cis_prep",
210        U_STRINGPREP_PROHIBITED_ERROR
211      },
212      {/*15*/
213 
214        "Deprecated U+202A",
215        "\xE2\x80\xAA", "\xCC\x81",
216        "nfs4_cis_prep",
217        U_STRINGPREP_PROHIBITED_ERROR
218      },
219      {/*16*/
220        "Language tagging character U+E0001",
221        "\xF3\xA0\x80\x81", "\xCC\x81",
222        "nfs4_cis_prep",
223        U_STRINGPREP_PROHIBITED_ERROR
224      },
225      {/*17*/
226        "Language tagging character U+E0042",
227        "\xF3\xA0\x81\x82", NULL,
228        "nfs4_cis_prep",
229        U_STRINGPREP_PROHIBITED_ERROR
230      },
231      {/*18*/
232        "Bidi: RandALCat character U+05BE and LCat characters",
233        "\x66\x6F\x6F\xD6\xBE\x62\x61\x72", NULL,
234        "nfs4_cis_prep",
235        U_STRINGPREP_CHECK_BIDI_ERROR
236      },
237      {/*19*/
238        "Bidi: RandALCat character U+FD50 and LCat characters",
239        "\x66\x6F\x6F\xEF\xB5\x90\x62\x61\x72", NULL,
240        "nfs4_cis_prep",
241        U_STRINGPREP_CHECK_BIDI_ERROR
242      },
243      {/*20*/
244        "Bidi: RandALCat character U+FB38 and LCat characters",
245        "\x66\x6F\x6F\xEF\xB9\xB6\x62\x61\x72", "\x66\x6F\x6F\x20\xd9\x8e\x62\x61\x72",
246        "nfs4_cis_prep",
247        U_ZERO_ERROR
248      },
249      {/*21*/
250        "Bidi: RandALCat without trailing RandALCat U+0627 U+0031",
251        "\xD8\xA7\x31", NULL,
252        "nfs4_cis_prep",
253        U_STRINGPREP_CHECK_BIDI_ERROR
254      },
255      {/*22*/
256        "Bidi: RandALCat character U+0627 U+0031 U+0628",
257        "\xD8\xA7\x31\xD8\xA8", "\xD8\xA7\x31\xD8\xA8",
258        "nfs4_cis_prep",
259        U_ZERO_ERROR
260      },
261      {/*23*/
262        "Unassigned code point U+E0002",
263        "\xF3\xA0\x80\x82", NULL,
264        "nfs4_cis_prep",
265        U_STRINGPREP_UNASSIGNED_ERROR
266      },
267 
268 /*  // Invalid UTF-8
269      {
270        "Larger test (shrinking)",
271        "X\xC2\xAD\xC3\xDF\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2"
272        "\xaa\xce\xb0\xe2\x80\x80", "xssi\xcc\x87""tel\xc7\xb0 a\xce\xb0 ",
273        "nfs4_cis_prep",
274         U_ZERO_ERROR
275      },
276     {
277 
278        "Larger test (expanding)",
279        "X\xC3\xDF\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80",
280        "xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88"
281        "\xe3\x83\xab""i\xcc\x87""tel\x28""d\x29\xe3\x82\xa2\xe3\x83\x91"
282        "\xe3\x83\xbc\xe3\x83\x88"
283        "nfs4_cis_prep",
284         U_ZERO_ERROR
285      },
286   */
287 };
288 
289 #define MAX_BUFFER_SIZE  1000
290 
291 static int32_t
unescapeData(const char * src,int32_t srcLen,char * dest,int32_t destCapacity,UErrorCode * status)292 unescapeData(const char* src, int32_t srcLen,
293              char* dest, int32_t destCapacity,
294              UErrorCode* status){
295 
296     UChar b1Stack[MAX_BUFFER_SIZE];
297     int32_t b1Capacity = MAX_BUFFER_SIZE,
298             b1Len      = 0,
299             destLen    = 0;
300 
301     UChar* b1 = b1Stack;
302 
303     b1Len = u_unescape(src,b1,b1Capacity);
304 
305     u_strToUTF8(dest, destCapacity, &destLen, b1, b1Len, status);
306 
307     return destLen;
308 }
309 
310 
Test_nfs4_cis_prep(void)311 static void Test_nfs4_cis_prep(void){
312     int32_t i=0;
313     UErrorCode loadStatus = U_ZERO_ERROR;
314     loadTestData(&loadStatus);
315     if (U_FAILURE(loadStatus)) {
316         log_data_err("Test could not initialize. Got %s\n", u_errorName(loadStatus));
317         return;
318     }
319 
320     for(i=0;i< (int32_t)(sizeof(conformanceTestCases)/sizeof(conformanceTestCases[0]));i++){
321         const char* src = conformanceTestCases[i].in;
322         UErrorCode status = U_ZERO_ERROR;
323         UParseError parseError;
324         UErrorCode expectedStatus = conformanceTestCases[i].expectedStatus;
325         const char* expectedDest = conformanceTestCases[i].out;
326         char* dest = NULL;
327         int32_t destLen = 0;
328 
329         destLen = nfs4_cis_prepare(src , (int32_t)strlen(src), dest, destLen, &parseError, &status);
330         if(status == U_BUFFER_OVERFLOW_ERROR){
331             status = U_ZERO_ERROR;
332             dest = (char*) malloc(++destLen);
333             destLen = nfs4_cis_prepare( src , (int32_t)strlen(src), dest, destLen, &parseError, &status);
334         }
335 
336         if(expectedStatus != status){
337             log_data_err("Did not get the expected status for nfs4_cis_prep at index %i. Expected: %s Got: %s - (Are you missing data?)\n",i, u_errorName(expectedStatus), u_errorName(status));
338         }
339         if(U_SUCCESS(status) && (strcmp(expectedDest,dest) !=0)){
340               log_err("Did not get the expected output for nfs4_cis_prep at index %i.\n", i);
341         }
342         free(dest);
343     }
344 }
345 
346 
347 
348 /*
349    There are several special identifiers ("who") which need to be
350    understood universally, rather than in the context of a particular
351    DNS domain.  Some of these identifiers cannot be understood when an
352    NFS client accesses the server, but have meaning when a local process
353    accesses the file.  The ability to display and modify these
354    permissions is permitted over NFS, even if none of the access methods
355    on the server understands the identifiers.
356 
357     Who                    Description
358    _______________________________________________________________
359 
360    "OWNER"                The owner of the file.
361    "GROUP"                The group associated with the file.
362    "EVERYONE"             The world.
363    "INTERACTIVE"          Accessed from an interactive terminal.
364    "NETWORK"              Accessed via the network.
365    "DIALUP"               Accessed as a dialup user to the server.
366    "BATCH"                Accessed from a batch job.
367    "ANONYMOUS"            Accessed without any authentication.
368    "AUTHENTICATED"        Any authenticated user (opposite of
369                           ANONYMOUS)
370    "SERVICE"              Access from a system service.
371 
372    To avoid conflict, these special identifiers are distinguish by an
373    appended "@" and should appear in the form "xxxx@" (note: no domain
374    name after the "@").  For example: ANONYMOUS@.
375 */
376 static const char* mixed_prep_data[] ={
377     "OWNER@",
378     "GROUP@",
379     "EVERYONE@",
380     "INTERACTIVE@",
381     "NETWORK@",
382     "DIALUP@",
383     "BATCH@",
384     "ANONYMOUS@",
385     "AUTHENTICATED@",
386     "\\u0930\\u094D\\u092E\\u094D\\u0915\\u094D\\u0937\\u0947\\u0924\\u094D@slip129-37-118-146.nc.us.ibm.net",
387     "\\u0936\\u094d\\u0930\\u0940\\u092e\\u0926\\u094d@saratoga.pe.utexas.edu",
388     "\\u092d\\u0917\\u0935\\u0926\\u094d\\u0917\\u0940\\u0924\\u093e@dial-120-45.ots.utexas.edu",
389     "\\u0905\\u0927\\u094d\\u092f\\u093e\\u092f@woo-085.dorms.waller.net",
390     "\\u0905\\u0930\\u094d\\u091c\\u0941\\u0928@hd30-049.hil.compuserve.com",
391     "\\u0935\\u093f\\u0937\\u093e\\u0926@pem203-31.pe.ttu.edu",
392     "\\u092f\\u094b\\u0917@56K-227.MaxTNT3.pdq.net",
393     "\\u0927\\u0943\\u0924\\u0930\\u093e\\u0937\\u094d\\u091f\\u094d\\u0930@dial-36-2.ots.utexas.edu",
394     "\\u0909\\u0935\\u093E\\u091A\\u0943@slip129-37-23-152.ga.us.ibm.net",
395     "\\u0927\\u0930\\u094d\\u092e\\u0915\\u094d\\u0937\\u0947\\u0924\\u094d\\u0930\\u0947@ts45ip119.cadvision.com",
396     "\\u0915\\u0941\\u0930\\u0941\\u0915\\u094d\\u0937\\u0947\\u0924\\u094d\\u0930\\u0947@sdn-ts-004txaustP05.dialsprint.net",
397     "\\u0938\\u092e\\u0935\\u0947\\u0924\\u093e@bar-tnt1s66.erols.com",
398     "\\u092f\\u0941\\u092f\\u0941\\u0924\\u094d\\u0938\\u0935\\u0903@101.st-louis-15.mo.dial-access.att.net",
399     "\\u092e\\u093e\\u092e\\u0915\\u093e\\u0903@h92-245.Arco.COM",
400     "\\u092a\\u093e\\u0923\\u094d\\u0921\\u0935\\u093e\\u0936\\u094d\\u091a\\u0948\\u0935@dial-13-2.ots.utexas.edu",
401     "\\u0915\\u093f\\u092e\\u0915\\u0941\\u0930\\u094d\\u0935\\u0924@net-redynet29.datamarkets.com.ar",
402     "\\u0938\\u0902\\u091c\\u0935@ccs-shiva28.reacciun.net.ve",
403     "\\u0c30\\u0c18\\u0c41\\u0c30\\u0c3e\\u0c2e\\u0c4d@7.houston-11.tx.dial-access.att.net",
404     "\\u0c35\\u0c3f\\u0c36\\u0c4d\\u0c35\\u0c28\\u0c3e\\u0c27@ingw129-37-120-26.mo.us.ibm.net",
405     "\\u0c06\\u0c28\\u0c02\\u0c26\\u0c4d@dialup6.austintx.com",
406     "\\u0C35\\u0C26\\u0C4D\\u0C26\\u0C3F\\u0C30\\u0C3E\\u0C1C\\u0C41@dns2.tpao.gov.tr",
407     "\\u0c30\\u0c3e\\u0c1c\\u0c40\\u0c35\\u0c4d@slip129-37-119-194.nc.us.ibm.net",
408     "\\u0c15\\u0c36\\u0c30\\u0c2c\\u0c3e\\u0c26@cs7.dillons.co.uk.203.119.193.in-addr.arpa",
409     "\\u0c38\\u0c02\\u0c1c\\u0c40\\u0c35\\u0c4d@swprd1.innovplace.saskatoon.sk.ca",
410     "\\u0c15\\u0c36\\u0c30\\u0c2c\\u0c3e\\u0c26@bikini.bologna.maraut.it",
411     "\\u0c38\\u0c02\\u0c1c\\u0c40\\u0c2c\\u0c4d@node91.subnet159-198-79.baxter.com",
412     "\\u0c38\\u0c46\\u0c28\\u0c4d\\u0c17\\u0c41\\u0c2a\\u0c4d\\u0c24@cust19.max5.new-york.ny.ms.uu.net",
413     "\\u0c05\\u0c2e\\u0c30\\u0c47\\u0c02\\u0c26\\u0c4d\\u0c30@balexander.slip.andrew.cmu.edu",
414     "\\u0c39\\u0c28\\u0c41\\u0c2e\\u0c3e\\u0c28\\u0c41\\u0c32@pool029.max2.denver.co.dynip.alter.net",
415     "\\u0c30\\u0c35\\u0c3f@cust49.max9.new-york.ny.ms.uu.net",
416     "\\u0c15\\u0c41\\u0c2e\\u0c3e\\u0c30\\u0c4d@s61.abq-dialin2.hollyberry.com",
417     "\\u0c35\\u0c3f\\u0c36\\u0c4d\\u0c35\\u0c28\\u0c3e\\u0c27@\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com",
418     "\\u0c06\\u0c26\\u0c3f\\u0c24\\u0c4d\\u0c2f@www.\\u00E0\\u00B3\\u00AF.com",
419     "\\u0C15\\u0C02\\u0C26\\u0C4D\\u0C30\\u0C47\\u0C17\\u0C41\\u0c32@www.\\u00C2\\u00A4.com",
420     "\\u0c36\\u0c4d\\u0c30\\u0c40\\u0C27\\u0C30\\u0C4D@www.\\u00C2\\u00A3.com",
421     "\\u0c15\\u0c02\\u0c1f\\u0c2e\\u0c36\\u0c46\\u0c1f\\u0c4d\\u0c1f\\u0c3f@\\u0025",
422     "\\u0c2e\\u0c3e\\u0c27\\u0c35\\u0c4d@\\u005C\\u005C",
423     "\\u0c26\\u0c46\\u0c36\\u0c46\\u0c1f\\u0c4d\\u0c1f\\u0c3f@www.\\u0021.com",
424     "test@www.\\u0024.com",
425     "help@\\u00C3\\u00BC.com",
426 
427 };
428 
429 
430 static void
Test_nfs4_mixed_prep(void)431 Test_nfs4_mixed_prep(void){
432     UErrorCode loadStatus = U_ZERO_ERROR;
433     loadTestData(&loadStatus);
434     if (U_FAILURE(loadStatus)) {
435         log_data_err("Test could not initialize. Got %s\n", u_errorName(loadStatus));
436         return;
437     }
438 
439     {
440         int32_t i=0;
441         char src[MAX_BUFFER_SIZE];
442         int32_t srcLen;
443 
444         for(i=0; i< UPRV_LENGTHOF(mixed_prep_data); i++){
445             int32_t destLen=0;
446             char* dest = NULL;
447             UErrorCode status = U_ZERO_ERROR;
448             UParseError parseError;
449             srcLen = unescapeData(mixed_prep_data[i], (int32_t)strlen(mixed_prep_data[i]), src, MAX_BUFFER_SIZE, &status);
450             if(U_FAILURE(status)){
451                 log_err("Conversion of data at index %i failed. Error: %s\n", i, u_errorName(status));
452                 continue;
453             }
454             destLen = nfs4_mixed_prepare(src, srcLen, NULL, 0, &parseError, &status);
455             if(status == U_BUFFER_OVERFLOW_ERROR){
456                 status = U_ZERO_ERROR;
457                 dest = (char*)malloc(++destLen);
458                 destLen = nfs4_mixed_prepare(src, srcLen, dest, destLen, &parseError, &status);
459             }
460             free(dest);
461             if(U_FAILURE(status)){
462                 log_data_err("Preparation of string at index %i failed. Error: %s - (Are you missing data?)\n", i, u_errorName(status));
463                 continue;
464             }
465         }
466     }
467     /* test the error condition */
468     {
469         const char* source = "OWNER@oss.software.ibm.com";
470         char dest[MAX_BUFFER_SIZE];
471         char src[MAX_BUFFER_SIZE] = {0};
472         UErrorCode status = U_ZERO_ERROR;
473         UParseError parseError;
474 
475         int32_t srcLen = unescapeData(source, (int32_t)strlen(source), src, MAX_BUFFER_SIZE, &status);
476 
477         nfs4_mixed_prepare(src, srcLen, dest, MAX_BUFFER_SIZE, &parseError, &status);
478 
479         if(status != U_PARSE_ERROR){
480             log_err("Did not get the expected error.Expected: %s Got: %s\n", u_errorName(U_PARSE_ERROR), u_errorName(status));
481         }
482     }
483 
484 
485 }
486 
487 static void
Test_nfs4_cs_prep(void)488 Test_nfs4_cs_prep(void){
489     UErrorCode errorCode = U_ZERO_ERROR;
490     loadTestData(&errorCode);
491     if(U_FAILURE(errorCode)) {
492         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode));
493         return;
494     }
495 
496     {
497         /* BiDi checking is turned off */
498         const char *source = "\\uC138\\uACC4\\uC758\\uBAA8\\uB4E0\\uC0AC\\uB78C\\uB4E4\\uC774\\u0644\\u064A\\u0647\\uD55C\\uAD6D\\uC5B4\\uB97C\\uC774\\uD574\\uD55C\\uB2E4\\uBA74";
499         UErrorCode status = U_ZERO_ERROR;
500         char src[MAX_BUFFER_SIZE]={'\0'};
501         UParseError parseError;
502         int32_t srcLen = unescapeData(source, (int32_t)strlen(source), src, MAX_BUFFER_SIZE, &status);
503         if(U_SUCCESS(status)){
504             char dest[MAX_BUFFER_SIZE] = {'\0'};
505             int32_t destLen = nfs4_cs_prepare(src, srcLen, dest, MAX_BUFFER_SIZE, FALSE, &parseError, &status);
506             if(U_FAILURE(status)){
507                 log_err("StringPrep failed for case: BiDi Checking Turned OFF with error: %s\n", u_errorName(status));
508             }
509             if(strcmp(dest,src)!=0){
510                 log_err("Did not get the expected output for case: BiDi Checking Turned OFF\n");
511             }
512             if(destLen != srcLen){
513                 log_err("Did not get the expected length for the output for case: BiDi Checking Turned OFF. Expected: %i Got: %i\n", srcLen, destLen);
514             }
515         }else{
516             log_err("Conversion failed for case: BiDi Checking Turned OFF with error: %s\n", u_errorName(status));
517         }
518     }
519     {
520         /* Normalization turned off */
521         const char *source = "www.\\u00E0\\u00B3\\u00AF.com";
522         UErrorCode status = U_ZERO_ERROR;
523         char src[MAX_BUFFER_SIZE]={'\0'};
524         UParseError parseError;
525         int32_t srcLen = unescapeData(source, (int32_t)strlen(source), src, MAX_BUFFER_SIZE, &status);
526         if(U_SUCCESS(status)){
527             char dest[MAX_BUFFER_SIZE] = {'\0'};
528             int32_t destLen = nfs4_cs_prepare(src, srcLen, dest, MAX_BUFFER_SIZE, FALSE, &parseError, &status);
529             if(U_FAILURE(status)){
530                 log_err("StringPrep failed for case: Normalization Turned OFF with error: %s\n", u_errorName(status));
531             }
532             if(strcmp(dest,src)!=0){
533                 log_err("Did not get the expected output for case: Normalization Turned OFF\n");
534             }
535             if(destLen != srcLen){
536                 log_err("Did not get the expected length for the output for case: Normalization Turned OFF. Expected: %i Got: %i\n", srcLen, destLen);
537             }
538         }else{
539             log_err("Conversion failed for case: Normalization Turned OFF with error: %s\n", u_errorName(status));
540         }
541     }
542     {
543         /* case mapping turned off */
544         const char *source = "THISISATEST";
545         UErrorCode status = U_ZERO_ERROR;
546         char src[MAX_BUFFER_SIZE]={'\0'};
547         UParseError parseError;
548         int32_t srcLen = unescapeData(source, (int32_t)strlen(source), src, MAX_BUFFER_SIZE, &status);
549         if(U_SUCCESS(status)){
550             char dest[MAX_BUFFER_SIZE] = {'\0'};
551             int32_t destLen = nfs4_cs_prepare(src, srcLen, dest, MAX_BUFFER_SIZE, TRUE, &parseError, &status);
552             if(U_FAILURE(status)){
553                 log_err("StringPrep failed for case: Case Mapping Turned OFF with error: %s\n", u_errorName(status));
554             }
555             if(strcmp(dest,src)!=0){
556                 log_err("Did not get the expected output for case: Case Mapping Turned OFF\n");
557             }
558             if(destLen != srcLen){
559                 log_err("Did not get the expected length for the output for case: Case Mapping Turned OFF. Expected: %i Got: %i\n", srcLen, destLen);
560             }
561         }else{
562             log_err("Conversion failed for case: Case Mapping Turned OFF with error: %s\n", u_errorName(status));
563         }
564     }
565     {
566         /* case mapping turned on */
567         const char *source = "THISISATEST";
568         const char *expected = "thisisatest";
569         UErrorCode status = U_ZERO_ERROR;
570         char src[MAX_BUFFER_SIZE]={'\0'};
571         char exp[MAX_BUFFER_SIZE]={'\0'};
572         UParseError parseError;
573         int32_t srcLen = unescapeData(source, (int32_t)strlen(source), src, MAX_BUFFER_SIZE, &status);
574         int32_t expLen = unescapeData(expected, (int32_t)strlen(expected), exp, MAX_BUFFER_SIZE, &status);
575         if(U_SUCCESS(status)){
576             char dest[MAX_BUFFER_SIZE] = {'\0'};
577             int32_t destLen = nfs4_cs_prepare(src, srcLen, dest, MAX_BUFFER_SIZE, FALSE, &parseError, &status);
578             if(U_FAILURE(status)){
579                 log_err("StringPrep failed for case: Case Mapping Turned On with error: %s\n", u_errorName(status));
580             }
581             if(strcmp(exp, dest)!=0){
582                 log_err("Did not get the expected output for case: Case Mapping Turned On!\n");
583             }
584             if(destLen != expLen){
585                 log_err("Did not get the expected length for the outputfor case: Case Mapping Turned On. Expected: %i Got: %i\n", strlen(expected), destLen);
586             }
587         }else{
588             log_err("Conversion failed for case: Case Mapping Turned ON with error: %s\n", u_errorName(status));
589         }
590     }
591 }
592 
593 
594 
TestBEAMWarning()595 static void TestBEAMWarning(){
596     UErrorCode status = U_ZERO_ERROR;
597     UParseError parseError;
598     UStringPrepProfile* profile = NULL;
599     /* get the test data path */
600     const char *testdatapath = NULL;
601     UChar src =0x0000;
602     testdatapath = loadTestData(&status);
603     if(U_FAILURE(status)) {
604         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
605         return;
606     }
607     /* open the profile */
608     profile = usprep_open(testdatapath, "nfscis",  &status);
609     usprep_prepare(profile,&src , 0, NULL, 0, USPREP_DEFAULT, &parseError, &status);
610 
611     usprep_close(profile);
612 }
613 
TestCoverage(void)614 static void TestCoverage(void) {
615     UErrorCode status = U_USELESS_COLLATOR_ERROR;
616     UParseError parseError;
617 
618     usprep_open(NULL, NULL, &status);
619     if (status != U_USELESS_COLLATOR_ERROR) {
620         log_err("usprep_open didn't react correctly to a bad UErrorCode\n");
621     }
622     usprep_prepare(NULL, NULL, 0, NULL, 0, USPREP_DEFAULT, &parseError, &status);
623     if (status != U_USELESS_COLLATOR_ERROR) {
624         log_err("usprep_prepare didn't react correctly to a bad UErrorCode\n");
625     }
626     status = U_ZERO_ERROR;
627     usprep_prepare(NULL, NULL, 0, NULL, 0, USPREP_DEFAULT, &parseError, &status);
628     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
629         log_err("usprep_prepare didn't check its arguments\n");
630     }
631 
632     /* Don't crash */
633     usprep_close(NULL);
634 }
635 
636 /**** Profile Test ****/
637 
638 #define SPREP_PROFILE_TEST_MAX_LENGTH 64
639 /* The format of the test cases should be the following:
640 * {
641 *     Profile name
642 *     src string1
643 *     expected result1
644 *     src string2
645 *     expected result2
646 *     ...
647 * }
648 *
649 * *Note: For expected failures add FAIL to beginning of the source string and for expected result use "FAIL".
650 */
651 static const char *profile_test_case[] = {
652 /**** RFC4013_SASLPREP ****/
653     "RFC4013_SASLPREP",
654     "user:\\u00A0\\u0AC6\\u1680\\u00ADpassword1",
655     "user: \\u0AC6 password1",
656 
657 /**** RFC4011_MIB ****/
658     "RFC4011_MIB",
659     "Policy\\u034F\\u200DBase\\u0020d\\u1806\\u200C",
660     "PolicyBase d",
661 
662 /**** RFC4505_TRACE ****/
663     "RFC4505_TRACE",
664     "Anony\\u0020\\u00A0mous\\u3000\\u0B9D\\u034F\\u00AD",
665     "Anony\\u0020\\u00A0mous\\u3000\\u0B9D\\u034F\\u00AD",
666 
667 /**** RFC4518_LDAP ****/
668     "RFC4518_LDAP",
669     "Ldap\\uFB01\\u00ADTest\\u0020\\u00A0\\u2062ing",
670     "LdapfiTest  ing",
671 
672 /**** RFC4518_LDAP_CI ****/
673     "RFC4518_LDAP_CI",
674     "Ldap\\uFB01\\u00ADTest\\u0020\\u00A0\\u2062ing12345",
675     "ldapfitest  ing12345",
676 
677 /**** RFC3920_RESOURCEPREP ****/
678     "RFC3920_RESOURCEPREP",
679     "ServerXM\\u2060\\uFE00\\uFE09PP s p ",
680     "ServerXMPP s p ",
681 
682 /**** RFC3920_NODEPREP ****/
683     "RFC3920_NODEPREP",
684     "Server\\u200DXMPPGreEK\\u03D0",
685     "serverxmppgreek\\u03B2",
686 
687 /**** RFC3722_ISCI ****/
688     "RFC3722_ISCSI",
689     "InternetSmallComputer\\uFB01\\u0032\\u2075Interface",
690     "internetsmallcomputerfi25interface",
691     "FAILThisShouldFailBecauseOfThis\\u002F",
692     "FAIL",
693 
694 /**** RFC3530_NFS4_CS_PREP ****/
695     "RFC3530_NFS4_CS_PREP",
696     "\\u00ADUser\\u2060Name@ \\u06DDDOMAIN.com",
697     "UserName@ \\u06DDDOMAIN.com",
698 
699 /**** RFC3530_NFS4_CS_PREP_CI ****/
700     "RFC3530_NFS4_CS_PREP_CI",
701     "\\u00ADUser\\u2060Name@ \\u06DDDOMAIN.com",
702     "username@ \\u06DDdomain.com",
703 
704 /**** RFC3530_NFS4_CIS_PREP ****/
705     "RFC3530_NFS4_CIS_PREP",
706     "AA\\u200C\\u200D @@DomAin.org",
707     "aa @@domain.org",
708 
709 /**** RFC3530_NFS4_MIXED_PREP_PREFIX ****/
710     "RFC3530_NFS4_MIXED_PREP_PREFIX",
711     "PrefixUser \\u007F\\uFB01End",
712     "PrefixUser \\u007FfiEnd",
713 
714 /**** RFC3530_NFS4_MIXED_PREP_SUFFIX ****/
715     "RFC3530_NFS4_MIXED_PREP_SUFFIX",
716     "SuffixDomain \\u007F\\uFB01EnD",
717     "suffixdomain \\u007Ffiend",
718 };
719 
getTypeFromProfileName(const char * profileName)720 UStringPrepProfileType getTypeFromProfileName(const char* profileName) {
721     if (uprv_strcmp(profileName, "RFC4013_SASLPREP") == 0) {
722         return USPREP_RFC4013_SASLPREP;
723     } else if (uprv_strcmp(profileName, "RFC4011_MIB") == 0) {
724         return USPREP_RFC4011_MIB;
725     } else if (uprv_strcmp(profileName, "RFC4505_TRACE") == 0) {
726         return USPREP_RFC4505_TRACE;
727     } else if (uprv_strcmp(profileName, "RFC4518_LDAP") == 0) {
728         return USPREP_RFC4518_LDAP;
729     } else if (uprv_strcmp(profileName, "RFC4518_LDAP_CI") == 0) {
730         return USPREP_RFC4518_LDAP_CI;
731     } else if (uprv_strcmp(profileName, "RFC3920_RESOURCEPREP") == 0) {
732         return USPREP_RFC3920_RESOURCEPREP;
733     } else if (uprv_strcmp(profileName, "RFC3920_NODEPREP") == 0) {
734         return USPREP_RFC3920_NODEPREP;
735     } else if (uprv_strcmp(profileName, "RFC3722_ISCSI") == 0) {
736         return USPREP_RFC3722_ISCSI;
737     } else if (uprv_strcmp(profileName, "RFC3530_NFS4_CS_PREP") == 0) {
738         return USPREP_RFC3530_NFS4_CS_PREP;
739     } else if (uprv_strcmp(profileName, "RFC3530_NFS4_CS_PREP_CI") == 0) {
740         return USPREP_RFC3530_NFS4_CS_PREP_CI;
741     } else if (uprv_strcmp(profileName, "RFC3530_NFS4_CIS_PREP") == 0) {
742         return USPREP_RFC3530_NFS4_CIS_PREP;
743     } else if (uprv_strcmp(profileName, "RFC3530_NFS4_MIXED_PREP_PREFIX") == 0) {
744         return USPREP_RFC3530_NFS4_MIXED_PREP_PREFIX;
745     } else if (uprv_strcmp(profileName, "RFC3530_NFS4_MIXED_PREP_SUFFIX") == 0) {
746         return USPREP_RFC3530_NFS4_MIXED_PREP_SUFFIX;
747     }
748     /* Should not happen. */
749     return USPREP_RFC3491_NAMEPREP;
750 }
TestStringPrepProfiles(void)751 static void TestStringPrepProfiles(void) {
752     UErrorCode status = U_ZERO_ERROR;
753     const char *profileName = NULL;
754     UChar src[SPREP_PROFILE_TEST_MAX_LENGTH];
755     UChar expected[SPREP_PROFILE_TEST_MAX_LENGTH];
756     UChar result[SPREP_PROFILE_TEST_MAX_LENGTH];
757     int32_t srcLength, resultLength, expectedLength;
758     int32_t i, testNum = 0;
759     UStringPrepProfile *sprep = NULL;
760 
761     for (i = 0; i < UPRV_LENGTHOF(profile_test_case); i++) {
762         if (uprv_strstr(profile_test_case[i], "RFC")) {
763             if (sprep != NULL) {
764                 usprep_close(sprep);
765                 sprep = NULL;
766             }
767             profileName = profile_test_case[i];
768             sprep = usprep_openByType(getTypeFromProfileName(profileName), &status);
769             if (U_FAILURE(status)) {
770                 log_data_err("Unable to open String Prep Profile with: %s\n", profileName);
771                 break;
772             }
773 
774             testNum = 0;
775             continue;
776         }
777         srcLength = resultLength = expectedLength = SPREP_PROFILE_TEST_MAX_LENGTH;
778 
779         testNum++;
780 
781         srcLength = u_unescape(profile_test_case[i], src, srcLength);
782         expectedLength = u_unescape(profile_test_case[++i], expected, expectedLength);
783 
784         resultLength = usprep_prepare(sprep, src, srcLength, result, resultLength, USPREP_ALLOW_UNASSIGNED, NULL, &status);
785         if (U_FAILURE(status)) {
786             if (uprv_strstr(profile_test_case[i], "FAIL") == NULL) {
787                 log_err("Error occurred on test[%d] for profile: %s\n", testNum, profileName);
788             } else {
789                 /* Error is expected so reset the status. */
790                 status = U_ZERO_ERROR;
791             }
792         } else {
793             if (uprv_strstr(profile_test_case[i], "FAIL") != NULL) {
794                 log_err("Error expected on test[%d] for profile: %s\n", testNum, profileName);
795             }
796 
797             if (resultLength != expectedLength || u_strcmp(result, expected) != 0) {
798                 log_err("Results do not match expected on test[%d] for profile: %s\n", testNum, profileName);
799             }
800         }
801     }
802 
803     if (sprep != NULL) {
804         usprep_close(sprep);
805     }
806 }
807 
808 #endif
809 
810 /*
811  * Hey, Emacs, please set the following:
812  *
813  * Local Variables:
814  * indent-tabs-mode: nil
815  * End:
816  *
817  */
818