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