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
28void addUStringPrepTest(TestNode** root);
29void doStringPrepTest(const char* binFileName, const char* txtFileName,
30                 int32_t options, UErrorCode* errorCode);
31
32static void Test_nfs4_cs_prep_data(void);
33static void Test_nfs4_cis_prep_data(void);
34static void Test_nfs4_mixed_prep_data(void);
35static void Test_nfs4_cs_prep(void);
36static void Test_nfs4_cis_prep(void);
37static void Test_nfs4_mixed_prep(void);
38static void TestBEAMWarning(void);
39static void TestCoverage(void);
40static void TestStringPrepProfiles(void);
41
42UStringPrepProfileType getTypeFromProfileName(const char* profileName);
43
44void
45addUStringPrepTest(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
60static void
61Test_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}
78static void
79Test_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}
84static void
85Test_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
102static 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
291static int32_t
292unescapeData(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
311static 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*/
376static 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
430static void
431Test_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
487static void
488Test_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
595static 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
614static 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*/
651static 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
720UStringPrepProfileType 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}
751static 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