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