1 /*
2  *******************************************************************************
3  *
4  *   Copyright (C) 2003-2014, International Business Machines
5  *   Corporation and others.  All Rights Reserved.
6  *
7  *******************************************************************************
8  *   file name:  testidna.cpp
9  *   encoding:   US-ASCII
10  *   tab size:   8 (not used)
11  *   indentation:4
12  *
13  *   created on: 2003feb1
14  *   created by: Ram Viswanadha
15  */
16 
17 #include "unicode/utypes.h"
18 
19 #if !UCONFIG_NO_IDNA && !UCONFIG_NO_TRANSLITERATION
20 
21 #include <time.h>
22 #include <limits.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include "unicode/localpointer.h"
26 #include "unicode/ustring.h"
27 #include "unicode/usprep.h"
28 #include "unicode/uniset.h"
29 #include "testidna.h"
30 #include "idnaref.h"
31 #include "nptrans.h"
32 #include "unicode/putil.h"
33 #include "idnaconf.h"
34 
35 static const UChar unicodeIn[][41] ={
36     {
37         0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
38         0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
39     },
40     {
41         0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
42         0x0000
43     },
44     {
45         0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
46         0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
47         0x0065, 0x0073, 0x006B, 0x0079, 0x0000
48     },
49     {
50         0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
51         0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
52         0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
53     },
54     {
55         0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
56         0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
57         0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
58         0x0939, 0x0948, 0x0902, 0x0000
59     },
60     {
61         0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
62         0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
63         0x0000
64     },
65 /*
66     {
67         0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
68         0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
69         0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
70     },
71 */
72     {
73         0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
74         0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
75         0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
76         0x0438, 0x0000
77     },
78     {
79         0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
80         0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
81         0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
82         0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
83         0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
84     },
85     {
86         0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
87         0x0000
88     },
89     {
90         0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
91         0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
92         0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
93         0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
94     },
95     {
96         0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
97     },
98     {
99         0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
100         0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
101         0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
102     },
103     {
104         0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
105         0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
106         0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
107     },
108     {
109         0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
110     },
111     {
112         0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
113         0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
114     },
115     {
116         0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
117         0x0000
118     },
119     {
120         0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
121     },
122     // test non-BMP code points
123     {
124         0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
125         0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
126         0x0000
127     },
128     {
129         0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
130         0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
131         0xD800, 0xDF21,
132         0x0000
133     },
134     // Greek
135     {
136         0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
137     },
138     // Maltese
139     {
140         0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
141         0x0127, 0x0061
142     },
143     // Russian
144     {
145         0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
146         0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
147         0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
148         0x0441, 0x0441, 0x043a, 0x0438
149     },
150     {
151         0xFB00, 0xFB01
152     }
153 
154 };
155 
156 static const char *asciiIn[] = {
157     "xn--egbpdaj6bu4bxfgehfvwxn",
158     "xn--ihqwcrb4cv8a8dqg056pqjye",
159     "xn--Proprostnemluvesky-uyb24dma41a",
160     "xn--4dbcagdahymbxekheh6e0a7fei0b",
161     "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
162     "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
163 /*  "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
164     "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
165     "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
166     "xn--ihqwctvzc91f659drss3x8bo0yb",
167     "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
168     "xn--3B-ww4c5e180e575a65lsy2b",
169     "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
170     "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
171     "xn--2-u9tlzr9756bt3uc0v",
172     "xn--MajiKoi5-783gue6qz075azm5e",
173     "xn--de-jg4avhby1noc0d",
174     "xn--d9juau41awczczp",
175     "XN--097CCDEKGHQJK",
176     "XN--db8CBHEJLGH4E0AL",
177     "xn--hxargifdar",                       // Greek
178     "xn--bonusaa-5bb1da",                   // Maltese
179     "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
180     "fffi"
181 };
182 
183 static const char *domainNames[] = {
184     "slip129-37-118-146.nc.us.ibm.net",
185     "saratoga.pe.utexas.edu",
186     "dial-120-45.ots.utexas.edu",
187     "woo-085.dorms.waller.net",
188     "hd30-049.hil.compuserve.com",
189     "pem203-31.pe.ttu.edu",
190     "56K-227.MaxTNT3.pdq.net",
191     "dial-36-2.ots.utexas.edu",
192     "slip129-37-23-152.ga.us.ibm.net",
193     "ts45ip119.cadvision.com",
194     "sdn-ts-004txaustP05.dialsprint.net",
195     "bar-tnt1s66.erols.com",
196     "101.st-louis-15.mo.dial-access.att.net",
197     "h92-245.Arco.COM",
198     "dial-13-2.ots.utexas.edu",
199     "net-redynet29.datamarkets.com.ar",
200     "ccs-shiva28.reacciun.net.ve",
201     "7.houston-11.tx.dial-access.att.net",
202     "ingw129-37-120-26.mo.us.ibm.net",
203     "dialup6.austintx.com",
204     "dns2.tpao.gov.tr",
205     "slip129-37-119-194.nc.us.ibm.net",
206     "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
207     "swprd1.innovplace.saskatoon.sk.ca",
208     "bikini.bologna.maraut.it",
209     "node91.subnet159-198-79.baxter.com",
210     "cust19.max5.new-york.ny.ms.uu.net",
211     "balexander.slip.andrew.cmu.edu",
212     "pool029.max2.denver.co.dynip.alter.net",
213     "cust49.max9.new-york.ny.ms.uu.net",
214     "s61.abq-dialin2.hollyberry.com",
215     "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
216     "www.xn--vea.com",
217    // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
218     "www.\\u00C2\\u00A4.com",
219     "www.\\u00C2\\u00A3.com",
220     // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
221     // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
222     //"@",
223     //"\\u002F",
224     //"www.\\u0021.com",
225     //"www.\\u0024.com",
226     //"\\u003f",
227     // These yeild U_IDNA_PROHIBITED_ERROR
228     //"\\u00CF\\u0082.com",
229     //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
230     //"\\u00E2\\u0098\\u00BA.com",
231     "\\u00C3\\u00BC.com",
232 
233 };
234 
235 typedef struct ErrorCases ErrorCases;
236 
237 static const struct ErrorCases{
238 
239     UChar unicode[100];
240     const char *ascii;
241     UErrorCode expected;
242     UBool useSTD3ASCIIRules;
243     UBool testToUnicode;
244     UBool testLabel;
245 } errorCases[] = {
246       {
247 
248         {
249             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
250             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
251             0x070F,/*prohibited*/
252             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
253             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
254             0x0000
255         },
256         "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
257         U_IDNA_PROHIBITED_ERROR,
258         FALSE, FALSE, TRUE
259     },
260 
261     {
262         {
263             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
264             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
265             0x0221, 0x0234/*Unassigned code points*/,
266             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
267             0x0000
268         },
269         "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
270 
271         U_IDNA_UNASSIGNED_ERROR,
272         FALSE, FALSE, TRUE
273     },
274     {
275         {
276             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
277             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
278             0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
279             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
280             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
281             0x0000
282         },
283         "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
284         U_IDNA_CHECK_BIDI_ERROR,
285         FALSE, FALSE, TRUE
286     },
287     {
288         {
289             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
290             /* labels cannot begin with an HYPHEN */
291             0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
292             0x002E,
293             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
294             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
295             0x0000
296 
297         },
298         "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
299         U_IDNA_STD3_ASCII_RULES_ERROR,
300         TRUE, FALSE, FALSE
301     },
302     {
303         {
304             /* correct ACE-prefix followed by unicode */
305             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
306             0x0078, 0x006e, 0x002d,0x002d,  /* ACE Prefix */
307             0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
308             0x002D,
309             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
310             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
311             0x0000
312 
313         },
314         /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
315         "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
316         U_IDNA_ACE_PREFIX_ERROR,
317         FALSE, FALSE, FALSE
318     },
319     /* cannot verify U_IDNA_VERIFICATION_ERROR */
320 
321     {
322       {
323         0x0077, 0x0077, 0x0077, 0x002e, /* www. */
324         0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
325         0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
326         0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
327         0x002e, 0x0063, 0x006f, 0x006d, /* com. */
328         0x0000
329       },
330       "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
331       U_IDNA_LABEL_TOO_LONG_ERROR,
332       FALSE, FALSE, TRUE
333     },
334 
335     {
336       {
337         0x0077, 0x0077, 0x0077, 0x002e, /* www. */
338         0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
339         0x002e, 0x0063, 0x006f, 0x006d, /* com. */
340         0x0000
341       },
342       "www.xn--01-tvdmo.com",
343       U_IDNA_CHECK_BIDI_ERROR,
344       FALSE, FALSE, TRUE
345     },
346 
347     {
348       {
349         0x0077, 0x0077, 0x0077, 0x002e, // www.
350         0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
351         0x002e, 0x0063, 0x006f, 0x006d, // com.
352         0x0000
353       },
354       "www.XN--ghbgi278xia.com",
355       U_IDNA_PROHIBITED_ERROR,
356       FALSE, FALSE, TRUE
357     },
358     {
359       {
360         0x0077, 0x0077, 0x0077, 0x002e, // www.
361         0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
362         0x002e, 0x0063, 0x006f, 0x006d, // com.
363         0x0000
364       },
365       "www.-abcde.com",
366       U_IDNA_STD3_ASCII_RULES_ERROR,
367       TRUE, FALSE, FALSE
368     },
369     {
370       {
371         0x0077, 0x0077, 0x0077, 0x002e, // www.
372         0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
373         0x002e, 0x0063, 0x006f, 0x006d, // com.
374         0x0000
375       },
376       "www.abcde-.com",
377       U_IDNA_STD3_ASCII_RULES_ERROR,
378       TRUE, FALSE, FALSE
379     },
380     {
381       {
382         0x0077, 0x0077, 0x0077, 0x002e, // www.
383         0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
384         0x002e, 0x0063, 0x006f, 0x006d, // com.
385         0x0000
386       },
387       "www.abcde@.com",
388       U_IDNA_STD3_ASCII_RULES_ERROR,
389       TRUE, FALSE, FALSE
390     },
391     {
392       {
393         0x0077, 0x0077, 0x0077, 0x002e, // www.
394         // zero length label
395         0x002e, 0x0063, 0x006f, 0x006d, // com.
396         0x0000
397       },
398       "www..com",
399       U_IDNA_ZERO_LENGTH_LABEL_ERROR,
400       TRUE, FALSE, FALSE
401     },
402     {
403       {0},
404       NULL,
405       U_ILLEGAL_ARGUMENT_ERROR,
406       TRUE, TRUE, FALSE
407     }
408 };
409 
410 
411 
412 
413 #define MAX_DEST_SIZE 300
414 
debug(const UChar * src,int32_t srcLength,int32_t options)415 void TestIDNA::debug(const UChar* src, int32_t srcLength, int32_t options){
416     UParseError parseError;
417     UErrorCode transStatus = U_ZERO_ERROR;
418     UErrorCode prepStatus  = U_ZERO_ERROR;
419     NamePrepTransform* trans = NamePrepTransform::createInstance(parseError,transStatus);
420     int32_t prepOptions = (((options & UIDNA_ALLOW_UNASSIGNED) != 0) ? USPREP_ALLOW_UNASSIGNED: 0);
421     LocalUStringPrepProfilePointer prep(usprep_openByType(USPREP_RFC3491_NAMEPREP,&prepStatus));
422     UChar *transOut=NULL, *prepOut=NULL;
423     int32_t transOutLength=0, prepOutLength=0;
424 
425 
426     transOutLength  = trans->process(src,srcLength,transOut, 0, prepOptions>0, &parseError, transStatus);
427     if( transStatus == U_BUFFER_OVERFLOW_ERROR){
428         transStatus = U_ZERO_ERROR;
429         transOut    = (UChar*) malloc(U_SIZEOF_UCHAR * transOutLength);
430         transOutLength = trans->process(src,srcLength,transOut, transOutLength, prepOptions>0, &parseError, transStatus);
431     }
432 
433     prepOutLength  = usprep_prepare(prep.getAlias(), src, srcLength, prepOut, 0, prepOptions, &parseError, &prepStatus);
434 
435     if( prepStatus == U_BUFFER_OVERFLOW_ERROR){
436         prepStatus = U_ZERO_ERROR;
437         prepOut    = (UChar*) malloc(U_SIZEOF_UCHAR * prepOutLength);
438         prepOutLength  = usprep_prepare(prep.getAlias(), src, srcLength, prepOut, prepOutLength, prepOptions, &parseError, &prepStatus);
439     }
440 
441     if(UnicodeString(transOut,transOutLength)!= UnicodeString(prepOut, prepOutLength)){
442         errln("Failed. Expected: " + prettify(UnicodeString(transOut, transOutLength))
443               + " Got: " + prettify(UnicodeString(prepOut,prepOutLength)));
444     }
445     free(transOut);
446     free(prepOut);
447     delete trans;
448 }
449 
testAPI(const UChar * src,const UChar * expected,const char * testName,UBool useSTD3ASCIIRules,UErrorCode expectedStatus,UBool doCompare,UBool testUnassigned,TestFunc func,UBool testSTD3ASCIIRules)450 void TestIDNA::testAPI(const UChar* src, const UChar* expected, const char* testName,
451             UBool useSTD3ASCIIRules,UErrorCode expectedStatus,
452             UBool doCompare, UBool testUnassigned, TestFunc func, UBool testSTD3ASCIIRules){
453 
454     UErrorCode status = U_ZERO_ERROR;
455     UChar destStack[MAX_DEST_SIZE];
456     int32_t destLen = 0;
457     UChar* dest = NULL;
458     int32_t expectedLen = (expected != NULL) ? u_strlen(expected) : 0;
459     int32_t options = (useSTD3ASCIIRules == TRUE) ? UIDNA_USE_STD3_RULES : UIDNA_DEFAULT;
460     UParseError parseError;
461     int32_t tSrcLen = 0;
462     UChar* tSrc = NULL;
463 
464     if(src != NULL){
465         tSrcLen = u_strlen(src);
466         tSrc  =(UChar*) malloc( U_SIZEOF_UCHAR * tSrcLen );
467         memcpy(tSrc,src,tSrcLen * U_SIZEOF_UCHAR);
468     }
469 
470     // test null-terminated source and return value of number of UChars required
471     destLen = func(src,-1,NULL,0,options, &parseError , &status);
472     if(status == U_BUFFER_OVERFLOW_ERROR){
473         status = U_ZERO_ERROR; // reset error code
474         if(destLen+1 < MAX_DEST_SIZE){
475             dest = destStack;
476             destLen = func(src,-1,dest,destLen+1,options, &parseError, &status);
477             // TODO : compare output with expected
478             if(U_SUCCESS(status) && expectedStatus != U_IDNA_STD3_ASCII_RULES_ERROR&& (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
479                 errln("Did not get the expected result for "+UnicodeString(testName) +" null terminated source. Expected : "
480                        + prettify(UnicodeString(expected,expectedLen))
481                        + " Got: " + prettify(UnicodeString(dest,destLen))
482                     );
483             }
484         }else{
485             errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName);
486         }
487     }
488 
489     if(status != expectedStatus){
490         errcheckln(status, "Did not get the expected error for "+
491                 UnicodeString(testName)+
492                 " null terminated source. Expected: " +UnicodeString(u_errorName(expectedStatus))
493                 + " Got: "+ UnicodeString(u_errorName(status))
494                 + " Source: " + prettify(UnicodeString(src))
495                );
496         free(tSrc);
497         return;
498     }
499     if(testUnassigned ){
500         status = U_ZERO_ERROR;
501         destLen = func(src,-1,NULL,0,options | UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
502         if(status == U_BUFFER_OVERFLOW_ERROR){
503             status = U_ZERO_ERROR; // reset error code
504             if(destLen+1 < MAX_DEST_SIZE){
505                 dest = destStack;
506                 destLen = func(src,-1,dest,destLen+1,options | UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
507                 // TODO : compare output with expected
508                 if(U_SUCCESS(status) && (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
509                     //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
510                     errln("Did not get the expected result for "+UnicodeString(testName) +
511                           " null terminated source "+ prettify(src) +
512                           " with both options set. Expected: "+  prettify(UnicodeString(expected,expectedLen))+
513                           "Got: " + prettify(UnicodeString(dest,destLen)));
514 
515                     debug(src,-1,options | UIDNA_ALLOW_UNASSIGNED);
516 
517                 }
518             }else{
519                 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName);
520             }
521         }
522         //testing query string
523         if(status != expectedStatus && expectedStatus != U_IDNA_UNASSIGNED_ERROR){
524                 errln( "Did not get the expected error for "+
525                     UnicodeString(testName)+
526                     " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus))
527                     + " Got: "+ UnicodeString(u_errorName(status))
528                     + " Source: " + prettify(UnicodeString(src))
529                    );
530         }
531     }
532 
533     status = U_ZERO_ERROR;
534 
535     // test source with lengthand return value of number of UChars required
536     destLen = func(tSrc, tSrcLen, NULL,0,options, &parseError, &status);
537     if(status == U_BUFFER_OVERFLOW_ERROR){
538         status = U_ZERO_ERROR; // reset error code
539         if(destLen+1 < MAX_DEST_SIZE){
540             dest = destStack;
541             destLen = func(src,u_strlen(src),dest,destLen+1,options, &parseError, &status);
542             // TODO : compare output with expected
543             if(U_SUCCESS(status) && (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
544                 errln("Did not get the expected result for %s with source length.\n",testName);
545             }
546         }else{
547             errln( "%s with source length  failed. Requires destCapacity > 300\n",testName);
548         }
549     }
550 
551     if(status != expectedStatus){
552         errln( "Did not get the expected error for "+
553                     UnicodeString(testName)+
554                     " with source length. Expected: " +UnicodeString(u_errorName(expectedStatus))
555                     + " Got: "+ UnicodeString(u_errorName(status))
556                     + " Source: " + prettify(UnicodeString(src))
557                    );
558     }
559     if(testUnassigned){
560         status = U_ZERO_ERROR;
561 
562         destLen = func(tSrc,tSrcLen,NULL,0,options | UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
563 
564         if(status == U_BUFFER_OVERFLOW_ERROR){
565             status = U_ZERO_ERROR; // reset error code
566             if(destLen+1 < MAX_DEST_SIZE){
567                 dest = destStack;
568                 destLen = func(src,u_strlen(src),dest,destLen+1,options | UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
569                 // TODO : compare output with expected
570                 if(U_SUCCESS(status) && (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
571                     errln("Did not get the expected result for %s with source length and both options set.\n",testName);
572                 }
573             }else{
574                 errln( "%s with source length  failed. Requires destCapacity > 300\n",testName);
575             }
576         }
577         //testing query string
578         if(status != expectedStatus && expectedStatus != U_IDNA_UNASSIGNED_ERROR){
579             errln( "Did not get the expected error for "+
580                     UnicodeString(testName)+
581                     " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus))
582                     + " Got: "+ UnicodeString(u_errorName(status))
583                     + " Source: " + prettify(UnicodeString(src))
584                    );
585         }
586     }
587 
588     status = U_ZERO_ERROR;
589     if(testSTD3ASCIIRules==TRUE){
590         destLen = func(src,-1,NULL,0,options | UIDNA_USE_STD3_RULES, &parseError, &status);
591         if(status == U_BUFFER_OVERFLOW_ERROR){
592             status = U_ZERO_ERROR; // reset error code
593             if(destLen+1 < MAX_DEST_SIZE){
594                 dest = destStack;
595                 destLen = func(src,-1,dest,destLen+1,options | UIDNA_USE_STD3_RULES, &parseError, &status);
596                 // TODO : compare output with expected
597                 if(U_SUCCESS(status) && (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
598                     //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
599                     errln("Did not get the expected result for "+UnicodeString(testName) +" null terminated source with both options set. Expected: "+ prettify(UnicodeString(expected,expectedLen)));
600 
601                 }
602             }else{
603                 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName);
604             }
605         }
606         //testing query string
607         if(status != expectedStatus){
608             errln( "Did not get the expected error for "+
609                         UnicodeString(testName)+
610                         " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus))
611                         + " Got: "+ UnicodeString(u_errorName(status))
612                         + " Source: " + prettify(UnicodeString(src))
613                        );
614         }
615 
616         status = U_ZERO_ERROR;
617 
618         destLen = func(tSrc,tSrcLen,NULL,0,options | UIDNA_USE_STD3_RULES, &parseError, &status);
619 
620         if(status == U_BUFFER_OVERFLOW_ERROR){
621             status = U_ZERO_ERROR; // reset error code
622             if(destLen+1 < MAX_DEST_SIZE){
623                 dest = destStack;
624                 destLen = func(src,u_strlen(src),dest,destLen+1,options | UIDNA_USE_STD3_RULES, &parseError, &status);
625                 // TODO : compare output with expected
626                 if(U_SUCCESS(status) && (doCompare==TRUE) && u_strCaseCompare(dest,destLen, expected,expectedLen,0,&status)!=0){
627                     errln("Did not get the expected result for %s with source length and both options set.\n",testName);
628                 }
629             }else{
630                 errln( "%s with source length  failed. Requires destCapacity > 300\n",testName);
631             }
632         }
633         //testing query string
634         if(status != expectedStatus && expectedStatus != U_IDNA_UNASSIGNED_ERROR){
635             errln( "Did not get the expected error for "+
636                         UnicodeString(testName)+
637                         " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus))
638                         + " Got: "+ UnicodeString(u_errorName(status))
639                         + " Source: " + prettify(UnicodeString(src))
640                        );
641         }
642     }
643     free(tSrc);
644 }
645 
testCompare(const UChar * s1,int32_t s1Len,const UChar * s2,int32_t s2Len,const char * testName,CompareFunc func,UBool isEqual)646 void TestIDNA::testCompare(const UChar* s1, int32_t s1Len,
647                         const UChar* s2, int32_t s2Len,
648                         const char* testName, CompareFunc func,
649                         UBool isEqual){
650 
651     UErrorCode status = U_ZERO_ERROR;
652     int32_t retVal = func(s1,-1,s2,-1,UIDNA_DEFAULT,&status);
653 
654     if(isEqual==TRUE &&  retVal !=0){
655         errln("Did not get the expected result for %s with null termniated strings.\n",testName);
656     }
657     if(U_FAILURE(status)){
658         errcheckln(status, "%s null terminated source failed. Error: %s", testName,u_errorName(status));
659     }
660 
661     status = U_ZERO_ERROR;
662     retVal = func(s1,-1,s2,-1,UIDNA_ALLOW_UNASSIGNED,&status);
663 
664     if(isEqual==TRUE &&  retVal !=0){
665         errln("Did not get the expected result for %s with null termniated strings with options set.\n", testName);
666     }
667     if(U_FAILURE(status)){
668         errcheckln(status, "%s null terminated source and options set failed. Error: %s",testName, u_errorName(status));
669     }
670 
671     status = U_ZERO_ERROR;
672     retVal = func(s1,s1Len,s2,s2Len,UIDNA_DEFAULT,&status);
673 
674     if(isEqual==TRUE &&  retVal !=0){
675         errln("Did not get the expected result for %s with string length.\n",testName);
676     }
677     if(U_FAILURE(status)){
678         errcheckln(status, "%s with string length. Error: %s",testName, u_errorName(status));
679     }
680 
681     status = U_ZERO_ERROR;
682     retVal = func(s1,s1Len,s2,s2Len,UIDNA_ALLOW_UNASSIGNED,&status);
683 
684     if(isEqual==TRUE &&  retVal !=0){
685         errln("Did not get the expected result for %s with string length and options set.\n",testName);
686     }
687     if(U_FAILURE(status)){
688         errcheckln(status, "%s with string length and options set. Error: %s", u_errorName(status), testName);
689     }
690 }
691 
testToASCII(const char * testName,TestFunc func)692 void TestIDNA::testToASCII(const char* testName, TestFunc func){
693 
694     int32_t i;
695     UChar buf[MAX_DEST_SIZE];
696 
697     for(i=0;i< (int32_t)(sizeof(unicodeIn)/sizeof(unicodeIn[0])); i++){
698         u_charsToUChars(asciiIn[i],buf, (int32_t)(strlen(asciiIn[i])+1));
699         testAPI(unicodeIn[i], buf,testName, FALSE,U_ZERO_ERROR, TRUE, TRUE, func);
700 
701     }
702 }
703 
testToUnicode(const char * testName,TestFunc func)704 void TestIDNA::testToUnicode(const char* testName, TestFunc func){
705 
706     int32_t i;
707     UChar buf[MAX_DEST_SIZE];
708 
709     for(i=0;i< (int32_t)(sizeof(asciiIn)/sizeof(asciiIn[0])); i++){
710         u_charsToUChars(asciiIn[i],buf, (int32_t)(strlen(asciiIn[i])+1));
711         testAPI(buf,unicodeIn[i],testName,FALSE,U_ZERO_ERROR, TRUE, TRUE, func);
712     }
713 }
714 
715 
testIDNToUnicode(const char * testName,TestFunc func)716 void TestIDNA::testIDNToUnicode(const char* testName, TestFunc func){
717     int32_t i;
718     UChar buf[MAX_DEST_SIZE];
719     UChar expected[MAX_DEST_SIZE];
720     UErrorCode status = U_ZERO_ERROR;
721     int32_t bufLen = 0;
722     UParseError parseError;
723     for(i=0;i< (int32_t)(sizeof(domainNames)/sizeof(domainNames[0])); i++){
724         bufLen = (int32_t)strlen(domainNames[i]);
725         bufLen = u_unescape(domainNames[i],buf, bufLen+1);
726         func(buf,bufLen,expected,MAX_DEST_SIZE, UIDNA_ALLOW_UNASSIGNED, &parseError,&status);
727         if(U_FAILURE(status)){
728             errcheckln(status, "%s failed to convert domainNames[%i].Error: %s",testName, i, u_errorName(status));
729             break;
730         }
731         testAPI(buf,expected,testName,FALSE,U_ZERO_ERROR, TRUE, TRUE, func);
732          //test toUnicode with all labels in the string
733         testAPI(buf,expected,testName, FALSE,U_ZERO_ERROR, TRUE, TRUE, func);
734         if(U_FAILURE(status)){
735             errln( "%s failed to convert domainNames[%i].Error: %s \n",testName,i, u_errorName(status));
736             break;
737         }
738     }
739 
740 }
741 
testIDNToASCII(const char * testName,TestFunc func)742 void TestIDNA::testIDNToASCII(const char* testName, TestFunc func){
743     int32_t i;
744     UChar buf[MAX_DEST_SIZE];
745     UChar expected[MAX_DEST_SIZE];
746     UErrorCode status = U_ZERO_ERROR;
747     int32_t bufLen = 0;
748     UParseError parseError;
749     for(i=0;i< (int32_t)(sizeof(domainNames)/sizeof(domainNames[0])); i++){
750         bufLen = (int32_t)strlen(domainNames[i]);
751         bufLen = u_unescape(domainNames[i],buf, bufLen+1);
752         func(buf,bufLen,expected,MAX_DEST_SIZE, UIDNA_ALLOW_UNASSIGNED, &parseError,&status);
753         if(U_FAILURE(status)){
754             errcheckln(status, "%s failed to convert domainNames[%i].Error: %s",testName,i, u_errorName(status));
755             break;
756         }
757         testAPI(buf,expected,testName, FALSE,U_ZERO_ERROR, TRUE, TRUE, func);
758         //test toASCII with all labels in the string
759         testAPI(buf,expected,testName, FALSE,U_ZERO_ERROR, FALSE, TRUE, func);
760         if(U_FAILURE(status)){
761             errln( "%s failed to convert domainNames[%i].Error: %s \n",testName,i, u_errorName(status));
762             break;
763         }
764     }
765 
766 }
767 
testCompare(const char * testName,CompareFunc func)768 void TestIDNA::testCompare(const char* testName, CompareFunc func){
769     int32_t i;
770 
771 
772     UChar www[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
773     UChar com[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x0000};
774     UChar buf[MAX_DEST_SIZE]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
775 
776     UnicodeString source(www), uni0(www),uni1(www), ascii0(www), ascii1(www);
777 
778     uni0.append(unicodeIn[0]);
779     uni0.append(com);
780     uni0.append((UChar)0x0000);
781 
782     uni1.append(unicodeIn[1]);
783     uni1.append(com);
784     uni1.append((UChar)0x0000);
785 
786     ascii0.append(asciiIn[0]);
787     ascii0.append(com);
788     ascii0.append((UChar)0x0000);
789 
790     ascii1.append(asciiIn[1]);
791     ascii1.append(com);
792     ascii1.append((UChar)0x0000);
793 
794     for(i=0;i< (int32_t)(sizeof(unicodeIn)/sizeof(unicodeIn[0])); i++){
795 
796         u_charsToUChars(asciiIn[i],buf+4, (int32_t)(strlen(asciiIn[i])+1));
797         u_strcat(buf,com);
798 
799         // for every entry in unicodeIn array
800         // prepend www. and append .com
801         source.truncate(4);
802         source.append(unicodeIn[i]);
803         source.append(com);
804         source.append((UChar)0x0000);
805         // a) compare it with itself
806         const UChar* src = source.getBuffer();
807         int32_t srcLen = u_strlen(src); //subtract null
808 
809         testCompare(src,srcLen,src,srcLen,testName, func, TRUE);
810 
811         // b) compare it with asciiIn equivalent
812         testCompare(src,srcLen,buf,u_strlen(buf),testName, func,TRUE);
813 
814         // c) compare it with unicodeIn not equivalent
815         if(i==0){
816             testCompare(src,srcLen,uni1.getBuffer(),uni1.length()-1,testName, func,FALSE);
817         }else{
818             testCompare(src,srcLen,uni0.getBuffer(),uni0.length()-1,testName, func,FALSE);
819         }
820         // d) compare it with asciiIn not equivalent
821         if(i==0){
822             testCompare(src,srcLen,ascii1.getBuffer(),ascii1.length()-1,testName, func,FALSE);
823         }else{
824             testCompare(src,srcLen,ascii0.getBuffer(),ascii0.length()-1,testName, func,FALSE);
825         }
826 
827     }
828 }
829 
830 #if 0
831 
832 static int32_t
833 getNextSeperator(UChar *src,int32_t srcLength,
834                  UChar **limit){
835     if(srcLength == -1){
836         int32_t i;
837         for(i=0 ; ;i++){
838             if(src[i] == 0){
839                 *limit = src + i; // point to null
840                 return i;
841             }
842             if(src[i]==0x002e){
843                 *limit = src + (i+1); // go past the delimiter
844                 return i;
845             }
846         }
847         // we have not found the delimiter
848         if(i==srcLength){
849             *limit = src+srcLength;
850         }
851         return i;
852     }else{
853         int32_t i;
854         for(i=0;i<srcLength;i++){
855             if(src[i]==0x002e){
856                 *limit = src + (i+1); // go past the delimiter
857                 return i;
858             }
859         }
860         // we have not found the delimiter
861         if(i==srcLength){
862             *limit = src+srcLength;
863         }
864         return i;
865     }
866 }
867 
868 void printPunycodeOutput(){
869 
870     UChar dest[MAX_DEST_SIZE];
871     int32_t destCapacity=MAX_DEST_SIZE;
872     UChar* start;
873     UChar* limit;
874     int32_t labelLen=0;
875     UBool caseFlags[MAX_DEST_SIZE];
876 
877     for(int32_t i=0;i< sizeof(errorCases)/sizeof(errorCases[0]);i++){
878         ErrorCases errorCase = errorCases[i];
879         UErrorCode status = U_ZERO_ERROR;
880         start = errorCase.unicode;
881         int32_t srcLen = u_strlen(start);
882         labelLen = getNextSeperator(start,srcLen,&limit);
883         start = limit;
884         labelLen=getNextSeperator(start,srcLen-labelLen,&limit);
885         int32_t destLen = u_strToPunycode(dest,destCapacity,start,labelLen,caseFlags, &status);
886         if(U_FAILURE(status)){
887             printf("u_strToPunycode failed for index %i\n",i);
888             continue;
889         }
890         for(int32_t j=0; j<destLen; j++){
891             printf("%c",(char)dest[j]);
892         }
893         printf("\n");
894     }
895 }
896 #endif
897 
testErrorCases(const char * IDNToASCIIName,TestFunc IDNToASCII,const char * IDNToUnicodeName,TestFunc IDNToUnicode)898 void TestIDNA::testErrorCases(const char* IDNToASCIIName, TestFunc IDNToASCII,
899                               const char* IDNToUnicodeName, TestFunc IDNToUnicode){
900     UChar buf[MAX_DEST_SIZE];
901     int32_t bufLen=0;
902 
903     for(int32_t i=0;i< (int32_t)(sizeof(errorCases)/sizeof(errorCases[0]));i++){
904         ErrorCases errorCase = errorCases[i];
905         UChar* src =NULL;
906         if(errorCase.ascii != NULL){
907             bufLen =  (int32_t)strlen(errorCase.ascii);
908             u_charsToUChars(errorCase.ascii,buf, bufLen+1);
909         }else{
910             bufLen = 1 ;
911             memset(buf,0,U_SIZEOF_UCHAR*MAX_DEST_SIZE);
912         }
913 
914         if(errorCase.unicode[0]!=0){
915             src = errorCase.unicode;
916         }
917         // test toASCII
918         testAPI(src,buf,
919                 IDNToASCIIName, errorCase.useSTD3ASCIIRules,
920                 errorCase.expected, TRUE, TRUE, IDNToASCII);
921         if(errorCase.testLabel ==TRUE){
922             testAPI(src,buf,
923                 IDNToASCIIName, errorCase.useSTD3ASCIIRules,
924                 errorCase.expected, FALSE,TRUE, IDNToASCII);
925         }
926         if(errorCase.testToUnicode ==TRUE){
927             testAPI((src==NULL)? NULL : buf,src,
928                     IDNToUnicodeName, errorCase.useSTD3ASCIIRules,
929                     errorCase.expected, TRUE, TRUE, IDNToUnicode);
930         }
931 
932     }
933 
934 }
935 /*
936 void TestIDNA::testConformance(const char* toASCIIName, TestFunc toASCII,
937                                const char* IDNToASCIIName, TestFunc IDNToASCII,
938                                const char* IDNToUnicodeName, TestFunc IDNToUnicode,
939                                const char* toUnicodeName, TestFunc toUnicode){
940     UChar src[MAX_DEST_SIZE];
941     int32_t srcLen=0;
942     UChar expected[MAX_DEST_SIZE];
943     int32_t expectedLen = 0;
944     for(int32_t i=0;i< (int32_t)(sizeof(conformanceTestCases)/sizeof(conformanceTestCases[0]));i++){
945         const char* utf8Chars1 = conformanceTestCases[i].in;
946         int32_t utf8Chars1Len = (int32_t)strlen(utf8Chars1);
947         const char* utf8Chars2 = conformanceTestCases[i].out;
948         int32_t utf8Chars2Len = (utf8Chars2 == NULL) ? 0 : (int32_t)strlen(utf8Chars2);
949 
950         UErrorCode status = U_ZERO_ERROR;
951         u_strFromUTF8(src,MAX_DEST_SIZE,&srcLen,utf8Chars1,utf8Chars1Len,&status);
952         if(U_FAILURE(status)){
953             errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
954             continue;
955         }
956         if(utf8Chars2 != NULL){
957             u_strFromUTF8(expected,MAX_DEST_SIZE,&expectedLen,utf8Chars2,utf8Chars2Len, &status);
958             if(U_FAILURE(status)){
959                 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
960                 continue;
961             }
962         }
963 
964         if(conformanceTestCases[i].expectedStatus != U_ZERO_ERROR){
965             // test toASCII
966             testAPI(src,expected,
967                     IDNToASCIIName, FALSE,
968                     conformanceTestCases[i].expectedStatus,
969                     TRUE,
970                     (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
971                     IDNToASCII);
972 
973             testAPI(src,expected,
974                     toASCIIName, FALSE,
975                     conformanceTestCases[i].expectedStatus, TRUE,
976                     (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
977                     toASCII);
978         }
979 
980         testAPI(src,src,
981                 IDNToUnicodeName, FALSE,
982                 conformanceTestCases[i].expectedStatus, TRUE, TRUE, IDNToUnicode);
983         testAPI(src,src,
984                 toUnicodeName, FALSE,
985                 conformanceTestCases[i].expectedStatus, TRUE, TRUE, toUnicode);
986 
987     }
988 
989 }
990 */
991 // test and ascertain
992 // func(func(func(src))) == func(src)
testChaining(const UChar * src,int32_t numIterations,const char * testName,UBool useSTD3ASCIIRules,UBool caseInsensitive,TestFunc func)993 void TestIDNA::testChaining(const UChar* src,int32_t numIterations,const char* testName,
994                   UBool useSTD3ASCIIRules, UBool caseInsensitive, TestFunc func){
995     UChar even[MAX_DEST_SIZE];
996     UChar odd[MAX_DEST_SIZE];
997     UChar expected[MAX_DEST_SIZE];
998     int32_t i=0,evenLen=0,oddLen=0,expectedLen=0;
999     UErrorCode status = U_ZERO_ERROR;
1000     int32_t srcLen = u_strlen(src);
1001     int32_t options = (useSTD3ASCIIRules == TRUE) ? UIDNA_USE_STD3_RULES : UIDNA_DEFAULT;
1002     UParseError parseError;
1003 
1004     // test null-terminated source
1005     expectedLen = func(src,-1,expected,MAX_DEST_SIZE, options, &parseError, &status);
1006     if(U_FAILURE(status)){
1007         errcheckln(status, "%s null terminated source failed. Error: %s",testName, u_errorName(status));
1008     }
1009     memcpy(odd,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1010     memcpy(even,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1011     for(;i<=numIterations; i++){
1012         if((i%2) ==0){
1013             evenLen = func(odd,-1,even,MAX_DEST_SIZE,options, &parseError, &status);
1014             if(U_FAILURE(status)){
1015                 errcheckln(status, "%s null terminated source failed - %s",testName, u_errorName(status));
1016                 break;
1017             }
1018         }else{
1019             oddLen = func(even,-1,odd,MAX_DEST_SIZE,options, &parseError, &status);
1020             if(U_FAILURE(status)){
1021                 errln("%s null terminated source failed\n",testName);
1022                 break;
1023             }
1024         }
1025     }
1026     if(caseInsensitive ==TRUE){
1027         if( u_strCaseCompare(even,evenLen, expected,expectedLen, 0, &status) !=0 ||
1028             u_strCaseCompare(odd,oddLen, expected,expectedLen, 0, &status) !=0 ){
1029 
1030             errln("Chaining for %s null terminated source failed\n",testName);
1031         }
1032     }else{
1033         if( u_strncmp(even,expected,expectedLen) != 0 ||
1034             u_strncmp(odd,expected,expectedLen) !=0 ){
1035 
1036             errln("Chaining for %s null terminated source failed\n",testName);
1037         }
1038     }
1039 
1040     // test null-terminated source
1041     status = U_ZERO_ERROR;
1042     expectedLen = func(src,-1,expected,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1043     if(U_FAILURE(status)){
1044         errcheckln(status, "%s null terminated source with options set failed. Error: %s",testName, u_errorName(status));
1045     }
1046     memcpy(odd,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1047     memcpy(even,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1048     for(;i<=numIterations; i++){
1049         if((i%2) ==0){
1050             evenLen = func(odd,-1,even,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1051             if(U_FAILURE(status)){
1052                 errcheckln(status, "%s null terminated source with options set failed - %s",testName, u_errorName(status));
1053                 break;
1054             }
1055         }else{
1056             oddLen = func(even,-1,odd,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1057             if(U_FAILURE(status)){
1058                 errln("%s null terminated source with options set failed\n",testName);
1059                 break;
1060             }
1061         }
1062     }
1063     if(caseInsensitive ==TRUE){
1064         if( u_strCaseCompare(even,evenLen, expected,expectedLen, 0, &status) !=0 ||
1065             u_strCaseCompare(odd,oddLen, expected,expectedLen, 0, &status) !=0 ){
1066 
1067             errln("Chaining for %s null terminated source with options set failed\n",testName);
1068         }
1069     }else{
1070         if( u_strncmp(even,expected,expectedLen) != 0 ||
1071             u_strncmp(odd,expected,expectedLen) !=0 ){
1072 
1073             errln("Chaining for %s null terminated source with options set failed\n",testName);
1074         }
1075     }
1076 
1077 
1078     // test source with length
1079     status = U_ZERO_ERROR;
1080     expectedLen = func(src,srcLen,expected,MAX_DEST_SIZE,options, &parseError, &status);
1081     if(U_FAILURE(status)){
1082         errcheckln(status, "%s null terminated source failed. Error: %s",testName, u_errorName(status));
1083     }
1084     memcpy(odd,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1085     memcpy(even,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1086     for(;i<=numIterations; i++){
1087         if((i%2) ==0){
1088             evenLen = func(odd,oddLen,even,MAX_DEST_SIZE,options, &parseError, &status);
1089             if(U_FAILURE(status)){
1090                 errcheckln(status, "%s source with source length failed - %s",testName, u_errorName(status));
1091                 break;
1092             }
1093         }else{
1094             oddLen = func(even,evenLen,odd,MAX_DEST_SIZE,options, &parseError, &status);
1095             if(U_FAILURE(status)){
1096                 errcheckln(status, "%s source with source length failed - %s",testName, u_errorName(status));
1097                 break;
1098             }
1099         }
1100     }
1101     if(caseInsensitive ==TRUE){
1102         if( u_strCaseCompare(even,evenLen, expected,expectedLen, 0, &status) !=0 ||
1103             u_strCaseCompare(odd,oddLen, expected,expectedLen, 0, &status) !=0 ){
1104 
1105             errln("Chaining for %s source with source length failed\n",testName);
1106         }
1107     }else{
1108         if( u_strncmp(even,expected,expectedLen) != 0 ||
1109             u_strncmp(odd,expected,expectedLen) !=0 ){
1110 
1111             errln("Chaining for %s source with source length failed\n",testName);
1112         }
1113     }
1114     status = U_ZERO_ERROR;
1115     expectedLen = func(src,srcLen,expected,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1116     if(U_FAILURE(status)){
1117         errcheckln(status, "%s null terminated source with options set failed. Error: %s",testName, u_errorName(status));
1118     }
1119     memcpy(odd,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1120     memcpy(even,expected,(expectedLen+1) * U_SIZEOF_UCHAR);
1121     for(;i<=numIterations; i++){
1122         if((i%2) ==0){
1123             evenLen = func(odd,oddLen,even,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1124             if(U_FAILURE(status)){
1125                 errcheckln(status, "%s source with source length and options set failed - %s",testName, u_errorName(status));
1126                 break;
1127             }
1128         }else{
1129             oddLen = func(even,evenLen,odd,MAX_DEST_SIZE,options|UIDNA_ALLOW_UNASSIGNED, &parseError, &status);
1130             if(U_FAILURE(status)){
1131                 errcheckln(status, "%s  source with source length and options set failed - %s",testName, u_errorName(status));
1132                 break;
1133             }
1134         }
1135     }
1136     if(caseInsensitive ==TRUE){
1137         if( u_strCaseCompare(even,evenLen, expected,expectedLen, 0, &status) !=0 ||
1138             u_strCaseCompare(odd,oddLen, expected,expectedLen, 0, &status) !=0 ){
1139 
1140             errln("Chaining for %s  source with source length and options set failed\n",testName);
1141         }
1142     }else{
1143         if( u_strncmp(even,expected,expectedLen) != 0 ||
1144             u_strncmp(odd,expected,expectedLen) !=0 ){
1145 
1146             errln("Chaining for %s  source with source length and options set failed\n",testName);
1147         }
1148     }
1149 }
testChaining(const char * toASCIIName,TestFunc toASCII,const char * toUnicodeName,TestFunc toUnicode)1150 void TestIDNA::testChaining(const char* toASCIIName, TestFunc toASCII,
1151                   const char* toUnicodeName, TestFunc toUnicode){
1152     int32_t i;
1153     UChar buf[MAX_DEST_SIZE];
1154 
1155     for(i=0;i< (int32_t)(sizeof(asciiIn)/sizeof(asciiIn[0])); i++){
1156         u_charsToUChars(asciiIn[i],buf, (int32_t)(strlen(asciiIn[i])+1));
1157         testChaining(buf,5,toUnicodeName, FALSE, FALSE, toUnicode);
1158     }
1159     for(i=0;i< (int32_t)(sizeof(unicodeIn)/sizeof(unicodeIn[0])); i++){
1160         testChaining(unicodeIn[i], 5,toASCIIName, FALSE, TRUE, toASCII);
1161     }
1162 }
1163 
1164 
testRootLabelSeparator(const char * testName,CompareFunc func,const char * IDNToASCIIName,TestFunc IDNToASCII,const char * IDNToUnicodeName,TestFunc IDNToUnicode)1165 void TestIDNA::testRootLabelSeparator(const char* testName, CompareFunc func,
1166                             const char* IDNToASCIIName, TestFunc IDNToASCII,
1167                             const char* IDNToUnicodeName, TestFunc IDNToUnicode){
1168     int32_t i;
1169 
1170 
1171     UChar www[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1172     UChar com[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x002E, /* root label separator */0x0000};
1173     UChar buf[MAX_DEST_SIZE]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1174 
1175     UnicodeString source(www), uni0(www),uni1(www), ascii0(www), ascii1(www);
1176 
1177     uni0.append(unicodeIn[0]);
1178     uni0.append(com);
1179     uni0.append((UChar)0x0000);
1180 
1181     uni1.append(unicodeIn[1]);
1182     uni1.append(com);
1183     uni1.append((UChar)0x0000);
1184 
1185     ascii0.append(asciiIn[0]);
1186     ascii0.append(com);
1187     ascii0.append((UChar)0x0000);
1188 
1189     ascii1.append(asciiIn[1]);
1190     ascii1.append(com);
1191     ascii1.append((UChar)0x0000);
1192 
1193     for(i=0;i< (int32_t)(sizeof(unicodeIn)/sizeof(unicodeIn[0])); i++){
1194 
1195         u_charsToUChars(asciiIn[i],buf+4, (int32_t)(strlen(asciiIn[i])+1));
1196         u_strcat(buf,com);
1197 
1198         // for every entry in unicodeIn array
1199         // prepend www. and append .com
1200         source.truncate(4);
1201         source.append(unicodeIn[i]);
1202         source.append(com);
1203         source.append((UChar)0x0000);
1204 
1205         const UChar* src = source.getBuffer();
1206         int32_t srcLen = u_strlen(src); //subtract null
1207 
1208         // b) compare it with asciiIn equivalent
1209         testCompare(src,srcLen,buf,u_strlen(buf),testName, func,TRUE);
1210 
1211         // a) compare it with itself
1212         testCompare(src,srcLen,src,srcLen,testName, func,TRUE);
1213 
1214 
1215         // IDNToASCII comparison
1216         testAPI(src,buf,IDNToASCIIName,FALSE,U_ZERO_ERROR,TRUE, TRUE, IDNToASCII);
1217         // IDNToUnicode comparison
1218         testAPI(buf,src,IDNToUnicodeName, FALSE,U_ZERO_ERROR, TRUE, TRUE, IDNToUnicode);
1219 
1220         // c) compare it with unicodeIn not equivalent
1221         if(i==0){
1222             testCompare(src,srcLen,uni1.getBuffer(),uni1.length()-1,testName, func,FALSE);
1223         }else{
1224             testCompare(src,srcLen,uni0.getBuffer(),uni0.length()-1,testName, func,FALSE);
1225         }
1226         // d) compare it with asciiIn not equivalent
1227         if(i==0){
1228             testCompare(src,srcLen,ascii1.getBuffer(),ascii1.length()-1,testName, func,FALSE);
1229         }else{
1230             testCompare(src,srcLen,ascii0.getBuffer(),ascii0.length()-1,testName, func,FALSE);
1231         }
1232     }
1233 }
1234 
1235 //---------------------------------------------
1236 // runIndexedTest
1237 //---------------------------------------------
1238 
1239 extern IntlTest *createUTS46Test();
1240 
runIndexedTest(int32_t index,UBool exec,const char * & name,char * par)1241 void TestIDNA::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par)
1242 {
1243     if (exec) logln((UnicodeString)"TestSuite IDNA API ");
1244     switch (index) {
1245 
1246         case 0: name = "TestToASCII"; if (exec) TestToASCII(); break;
1247         case 1: name = "TestToUnicode"; if (exec) TestToUnicode(); break;
1248         case 2: name = "TestIDNToASCII"; if (exec) TestIDNToASCII(); break;
1249         case 3: name = "TestIDNToUnicode"; if (exec) TestIDNToUnicode(); break;
1250         case 4: name = "TestCompare"; if (exec) TestCompare(); break;
1251         case 5: name = "TestErrorCases"; if (exec) TestErrorCases(); break;
1252         case 6: name = "TestChaining"; if (exec) TestChaining(); break;
1253         case 7: name = "TestRootLabelSeparator"; if(exec) TestRootLabelSeparator(); break;
1254         case 8: name = "TestCompareReferenceImpl"; if(exec) TestCompareReferenceImpl(); break;
1255         case 9: name = "TestDataFile"; if(exec) TestDataFile(); break;
1256 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1257         case 10: name = "TestRefIDNA"; if(exec) TestRefIDNA(); break;
1258         case 11: name = "TestIDNAMonkeyTest"; if(exec) TestIDNAMonkeyTest(); break;
1259 #else
1260         case 10: case 11: name = "skip"; break;
1261 #endif
1262         case 12:
1263             {
1264                 name = "TestConformanceTestVectors";
1265                 if(exec){
1266                     logln("TestSuite IDNA conf----"); logln();
1267                     IdnaConfTest test;
1268                     callTest(test, par);
1269                 }
1270                 break;
1271             }
1272         case 13:
1273             name = "UTS46Test";
1274             if (exec) {
1275                 logln("TestSuite UTS46Test---"); logln();
1276                 LocalPointer<IntlTest> test(createUTS46Test());
1277                 callTest(*test, par);
1278             }
1279             break;
1280         default: name = ""; break; /*needed to end loop*/
1281     }
1282 }
TestToASCII()1283 void TestIDNA::TestToASCII(){
1284     testToASCII("uidna_toASCII", uidna_toASCII);
1285 }
TestToUnicode()1286 void TestIDNA::TestToUnicode(){
1287     testToUnicode("uidna_toUnicode", uidna_toUnicode);
1288 }
TestIDNToASCII()1289 void TestIDNA::TestIDNToASCII(){
1290     testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII);
1291 }
TestIDNToUnicode()1292 void TestIDNA::TestIDNToUnicode(){
1293     testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode);
1294 }
TestCompare()1295 void TestIDNA::TestCompare(){
1296     testCompare("uidna_compare",uidna_compare);
1297 }
TestErrorCases()1298 void TestIDNA::TestErrorCases(){
1299     testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII,
1300                     "uidna_IDNToUnicode",uidna_IDNToUnicode);
1301 }
TestRootLabelSeparator()1302 void TestIDNA::TestRootLabelSeparator(){
1303     testRootLabelSeparator( "uidna_compare",uidna_compare,
1304                             "uidna_IDNToASCII", uidna_IDNToASCII,
1305                             "uidna_IDNToUnicode",uidna_IDNToUnicode
1306                             );
1307 }
TestChaining()1308 void TestIDNA::TestChaining(){
1309     testChaining("uidna_toASCII",uidna_toASCII, "uidna_toUnicode", uidna_toUnicode);
1310 }
1311 
1312 
1313 static const int loopCount = 100;
1314 static const int maxCharCount = 20;
1315 
1316 static uint32_t
randul()1317 randul()
1318 {
1319     static UBool initialized = FALSE;
1320     if (!initialized)
1321     {
1322         srand((unsigned)time(NULL));
1323         initialized = TRUE;
1324     }
1325     // Assume rand has at least 12 bits of precision
1326     uint32_t l = 0;
1327     for (uint32_t i=0; i<sizeof(l); ++i)
1328         ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4);
1329     return l;
1330 }
1331 
1332 /**
1333  * Return a random integer i where 0 <= i < n.
1334  * A special function that gets random codepoints from planes 0,1,2 and 14
1335  */
rand_uni()1336 static int32_t rand_uni()
1337 {
1338    int32_t retVal = (int32_t)(randul()& 0x3FFFF);
1339    if(retVal >= 0x30000){
1340        retVal+=0xB0000;
1341    }
1342    return retVal;
1343 }
1344 
randi(int32_t n)1345 static int32_t randi(int32_t n){
1346     return (int32_t) (randul() % (n+1));
1347 }
1348 
getTestSource(UnicodeString & fillIn)1349 void getTestSource(UnicodeString& fillIn) {
1350     int32_t i = 0;
1351     int32_t charCount = (randi(maxCharCount) + 1);
1352     while (i <charCount ) {
1353         int32_t codepoint = rand_uni();
1354         if(codepoint == 0x0000){
1355             continue;
1356         }
1357         fillIn.append((UChar32)codepoint);
1358         i++;
1359     }
1360 
1361 }
1362 
testCompareReferenceImpl(UnicodeString & src,TestFunc refIDNA,const char * refIDNAName,TestFunc uIDNA,const char * uIDNAName,int32_t options)1363 UnicodeString TestIDNA::testCompareReferenceImpl(UnicodeString& src,
1364                                         TestFunc refIDNA, const char* refIDNAName,
1365                                         TestFunc uIDNA, const char* uIDNAName,
1366                                         int32_t options){
1367 
1368     const UChar* srcUChars = src.getBuffer();
1369     UChar exp[MAX_DEST_SIZE]={0};
1370     int32_t expCap = MAX_DEST_SIZE, expLen=0;
1371     UErrorCode expStatus = U_ZERO_ERROR;
1372     UParseError parseError;
1373 
1374     logln("Comparing "+ UnicodeString(refIDNAName)
1375            + " with "+ UnicodeString(uIDNAName)
1376            +" for input: " + prettify(srcUChars));
1377 
1378     expLen = refIDNA(srcUChars, src.length()-1, exp, expCap,
1379                       options, &parseError, &expStatus);
1380 
1381     UChar got[MAX_DEST_SIZE]={0};
1382     int32_t gotCap = MAX_DEST_SIZE, gotLen=0;
1383     UErrorCode gotStatus = U_ZERO_ERROR;
1384 
1385     gotLen = uIDNA(srcUChars, src.length()-1, got, gotCap,
1386                    options, &parseError, &gotStatus);
1387 
1388     if(expStatus != gotStatus){
1389         errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName)
1390                + " with " + UnicodeString(uIDNAName)
1391                + " Expected: " + UnicodeString(u_errorName(expStatus))
1392                + " Got: " + UnicodeString(u_errorName(gotStatus))
1393                + " for Source: "+ prettify(srcUChars)
1394                + " Options: " + options);
1395         return UnicodeString("");
1396     }
1397 
1398     // now we know that both implementations yielded same error
1399     if(U_SUCCESS(expStatus)){
1400         // compare the outputs if status == U_ZERO_ERROR
1401         if(u_strCompare(exp, expLen, got, gotLen, TRUE) != 0){
1402             errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName)
1403                + " with " + UnicodeString(uIDNAName)
1404                + " Expected: " + prettify(UnicodeString(exp, expLen))
1405                + " Got: " + prettify(UnicodeString(got, gotLen))
1406                + " for Source: "+ prettify(srcUChars)
1407                + " Options: " + options);
1408         }
1409         return UnicodeString(exp, expLen);
1410 
1411     }else{
1412         logln("Got the same error while comparing "
1413             + UnicodeString(refIDNAName)
1414             + " with "+ UnicodeString(uIDNAName)
1415             +" for input: " + prettify(srcUChars));
1416     }
1417     return UnicodeString("");
1418 }
1419 
testCompareReferenceImpl(const UChar * src,int32_t srcLen)1420 void TestIDNA::testCompareReferenceImpl(const UChar* src, int32_t srcLen){
1421     UnicodeString label(src,srcLen);
1422     label.append((UChar)0x0000);
1423 
1424     //test idnaref_toASCII and idnare
1425     UnicodeString asciiLabel = testCompareReferenceImpl(label,
1426                                                       idnaref_toASCII, "idnaref_toASCII",
1427                                                       uidna_toASCII, "uidna_toASCII",
1428                                                       UIDNA_ALLOW_UNASSIGNED);
1429     testCompareReferenceImpl(label,
1430                               idnaref_toASCII, "idnaref_toASCII",
1431                               uidna_toASCII, "uidna_toASCII",
1432                               UIDNA_DEFAULT);
1433     testCompareReferenceImpl(label,
1434                               idnaref_toASCII, "idnaref_toASCII",
1435                               uidna_toASCII, "uidna_toASCII",
1436                               UIDNA_USE_STD3_RULES);
1437     testCompareReferenceImpl(label,
1438                               idnaref_toASCII, "idnaref_toASCII",
1439                               uidna_toASCII, "uidna_toASCII",
1440                               UIDNA_USE_STD3_RULES | UIDNA_ALLOW_UNASSIGNED);
1441 
1442     if(asciiLabel.length()!=0){
1443         asciiLabel.append((UChar)0x0000);
1444 
1445         // test toUnciode
1446         testCompareReferenceImpl(asciiLabel,
1447                                   idnaref_toUnicode, "idnaref_toUnicode",
1448                                   uidna_toUnicode, "uidna_toUnicode",
1449                                   UIDNA_ALLOW_UNASSIGNED);
1450         testCompareReferenceImpl(asciiLabel,
1451                                   idnaref_toUnicode, "idnaref_toUnicode",
1452                                   uidna_toUnicode, "uidna_toUnicode",
1453                                   UIDNA_DEFAULT);
1454         testCompareReferenceImpl(asciiLabel,
1455                                   idnaref_toUnicode, "idnaref_toUnicode",
1456                                   uidna_toUnicode, "uidna_toUnicode",
1457                                   UIDNA_USE_STD3_RULES);
1458         testCompareReferenceImpl(asciiLabel,
1459                                   idnaref_toUnicode, "idnaref_toUnicode",
1460                                   uidna_toUnicode, "uidna_toUnicode",
1461                                   UIDNA_USE_STD3_RULES | UIDNA_ALLOW_UNASSIGNED);
1462     }
1463 
1464 }
1465 const char* failures[] ={
1466     "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1467     "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1468 };
1469 
TestIDNAMonkeyTest()1470 void TestIDNA::TestIDNAMonkeyTest(){
1471     UnicodeString source;
1472     UErrorCode status = U_ZERO_ERROR;
1473     int i;
1474 
1475     getInstance(status);    // Init prep
1476     if (U_FAILURE(status)) {
1477         dataerrln("Test could not initialize. Got %s", u_errorName(status));
1478         return;
1479     }
1480 
1481     for(i=0; i<loopCount; i++){
1482         source.truncate(0);
1483         getTestSource(source);
1484         source.append((UChar)0x0000);
1485         const UChar* src = source.getBuffer();
1486         testCompareReferenceImpl(src,source.length()-1);
1487         testCompareReferenceImpl(src,source.length()-1);
1488     }
1489 
1490     /* for debugging */
1491     for (i=0; i<(int)(sizeof(failures)/sizeof(failures[0])); i++){
1492         source.truncate(0);
1493         source.append( UnicodeString(failures[i], -1, US_INV) );
1494         source = source.unescape();
1495         source.append((UChar)0x0000);
1496         const UChar *src = source.getBuffer();
1497         testCompareReferenceImpl(src,source.length()-1);
1498         //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1499     }
1500 
1501 
1502     source.truncate(0);
1503     source.append(UNICODE_STRING_SIMPLE("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C"));
1504     debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1505 
1506     { // test deletion of code points
1507         UnicodeString source("\\u043f\\u00AD\\u034f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV);
1508         source = source.unescape();
1509         UnicodeString expected("\\u043f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV);
1510         expected = expected.unescape();
1511         UnicodeString ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1512         ascii.append((UChar)0x0000);
1513         testAPI(source.getBuffer(),ascii.getBuffer(), "uidna_toASCII", FALSE, U_ZERO_ERROR, TRUE, TRUE, uidna_toASCII);
1514 
1515         testAPI(source.getBuffer(),ascii.getBuffer(), "idnaref_toASCII", FALSE, U_ZERO_ERROR, TRUE, TRUE, idnaref_toASCII);
1516 
1517         testCompareReferenceImpl(source.getBuffer(), source.length()-1);
1518     }
1519 
1520 }
1521 
TestCompareReferenceImpl()1522 void TestIDNA::TestCompareReferenceImpl(){
1523 
1524     UChar src [2] = {0,0};
1525     int32_t srcLen = 0;
1526 
1527     // data even OK?
1528     {
1529       UErrorCode dataStatus = U_ZERO_ERROR;
1530       loadTestData(dataStatus);
1531       if(U_FAILURE(dataStatus)) {
1532         dataerrln("Couldn't load test data: %s\n", u_errorName(dataStatus)); // save us from thousands and thousands of errors
1533         return;
1534       }
1535     }
1536 
1537     for (int32_t i = 0; i <= 0x10FFFF; i++){
1538         if (quick == TRUE && i > 0x0FFF){
1539             return;
1540         }
1541         if(i == 0x30000){
1542             // jump to E0000, no characters assigned in plain 3 to plain 13 as of Unicode 6.0
1543             i = 0xE0000;
1544         }
1545         if (i > 0xFFFF){
1546             src[0] = U16_LEAD(i);
1547             src[1] = U16_TRAIL(i);
1548             srcLen =2;
1549         } else {
1550             src[0] = (UChar)i;
1551             src[1] = 0;
1552             srcLen = 1;
1553         }
1554         testCompareReferenceImpl(src, srcLen);
1555     }
1556 }
1557 
TestRefIDNA()1558 void TestIDNA::TestRefIDNA(){
1559     UErrorCode status = U_ZERO_ERROR;
1560     getInstance(status);    // Init prep
1561     if (U_FAILURE(status)) {
1562         if (status == U_FILE_ACCESS_ERROR) {
1563             dataerrln("Test could not initialize. Got %s", u_errorName(status));
1564         }
1565         return;
1566     }
1567 
1568     testToASCII("idnaref_toASCII", idnaref_toASCII);
1569     testToUnicode("idnaref_toUnicode", idnaref_toUnicode);
1570     testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII);
1571     testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode);
1572     testCompare("idnaref_compare",idnaref_compare);
1573     testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII,
1574                     "idnaref_IDNToUnicode",idnaref_IDNToUnicode);
1575     testChaining("idnaref_toASCII",idnaref_toASCII, "idnaref_toUnicode", idnaref_toUnicode);
1576 
1577     testRootLabelSeparator( "idnaref_compare",idnaref_compare,
1578                             "idnaref_IDNToASCII", idnaref_IDNToASCII,
1579                             "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1580                             );
1581     testChaining("idnaref_toASCII",idnaref_toASCII, "idnaref_toUnicode", idnaref_toUnicode);
1582 }
1583 
1584 
TestDataFile()1585 void TestIDNA::TestDataFile(){
1586      testData(*this);
1587 }
~TestIDNA()1588 TestIDNA::~TestIDNA(){
1589     if(gPrep!=NULL){
1590         delete gPrep;
1591         gPrep = NULL;
1592     }
1593 }
1594 
1595 NamePrepTransform* TestIDNA::gPrep = NULL;
1596 
getInstance(UErrorCode & status)1597 NamePrepTransform* TestIDNA::getInstance(UErrorCode& status){
1598     if(TestIDNA::gPrep == NULL){
1599         UParseError parseError;
1600         TestIDNA::gPrep = NamePrepTransform::createInstance(parseError, status);
1601         if(TestIDNA::gPrep ==NULL){
1602            //status = U_MEMORY_ALLOCATION_ERROR;
1603            return NULL;
1604         }
1605     }
1606     return TestIDNA::gPrep;
1607 
1608 }
1609 #endif /* #if !UCONFIG_NO_IDNA */
1610