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