• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *******************************************************************************
3  *
4  *   Copyright (C) 2003-2007, 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/ustring.h"
26 #include "unicode/usprep.h"
27 #include "unicode/uniset.h"
28 #include "testidna.h"
29 #include "idnaref.h"
30 #include "nptrans.h"
31 #include "unicode/putil.h"
32 #include "idnaconf.h"
33 
34 static const UChar unicodeIn[][41] ={
35     {
36         0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
37         0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
38     },
39     {
40         0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
41         0x0000
42     },
43     {
44         0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
45         0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
46         0x0065, 0x0073, 0x006B, 0x0079, 0x0000
47     },
48     {
49         0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
50         0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
51         0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
52     },
53     {
54         0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
55         0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
56         0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
57         0x0939, 0x0948, 0x0902, 0x0000
58     },
59     {
60         0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
61         0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
62         0x0000
63     },
64 /*
65     {
66         0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
67         0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
68         0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
69     },
70 */
71     {
72         0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
73         0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
74         0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
75         0x0438, 0x0000
76     },
77     {
78         0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
79         0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
80         0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
81         0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
82         0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
83     },
84     {
85         0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
86         0x0000
87     },
88     {
89         0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
90         0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
91         0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
92         0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
93     },
94     {
95         0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
96     },
97     {
98         0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
99         0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
100         0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
101     },
102     {
103         0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
104         0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
105         0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
106     },
107     {
108         0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
109     },
110     {
111         0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
112         0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
113     },
114     {
115         0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
116         0x0000
117     },
118     {
119         0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
120     },
121     // test non-BMP code points
122     {
123         0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
124         0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
125         0x0000
126     },
127     {
128         0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
129         0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
130         0xD800, 0xDF21,
131         0x0000
132     },
133     // Greek
134     {
135         0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
136     },
137     // Maltese
138     {
139         0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
140         0x0127, 0x0061
141     },
142     // Russian
143     {
144         0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
145         0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
146         0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
147         0x0441, 0x0441, 0x043a, 0x0438
148     },
149     {
150         0xFB00, 0xFB01
151     }
152 
153 };
154 
155 static const char *asciiIn[] = {
156     "xn--egbpdaj6bu4bxfgehfvwxn",
157     "xn--ihqwcrb4cv8a8dqg056pqjye",
158     "xn--Proprostnemluvesky-uyb24dma41a",
159     "xn--4dbcagdahymbxekheh6e0a7fei0b",
160     "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
161     "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
162 /*  "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
163     "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
164     "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
165     "xn--ihqwctvzc91f659drss3x8bo0yb",
166     "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
167     "xn--3B-ww4c5e180e575a65lsy2b",
168     "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
169     "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
170     "xn--2-u9tlzr9756bt3uc0v",
171     "xn--MajiKoi5-783gue6qz075azm5e",
172     "xn--de-jg4avhby1noc0d",
173     "xn--d9juau41awczczp",
174     "XN--097CCDEKGHQJK",
175     "XN--db8CBHEJLGH4E0AL",
176     "xn--hxargifdar",                       // Greek
177     "xn--bonusaa-5bb1da",                   // Maltese
178     "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
179     "fffi"
180 };
181 
182 static const char *domainNames[] = {
183     "slip129-37-118-146.nc.us.ibm.net",
184     "saratoga.pe.utexas.edu",
185     "dial-120-45.ots.utexas.edu",
186     "woo-085.dorms.waller.net",
187     "hd30-049.hil.compuserve.com",
188     "pem203-31.pe.ttu.edu",
189     "56K-227.MaxTNT3.pdq.net",
190     "dial-36-2.ots.utexas.edu",
191     "slip129-37-23-152.ga.us.ibm.net",
192     "ts45ip119.cadvision.com",
193     "sdn-ts-004txaustP05.dialsprint.net",
194     "bar-tnt1s66.erols.com",
195     "101.st-louis-15.mo.dial-access.att.net",
196     "h92-245.Arco.COM",
197     "dial-13-2.ots.utexas.edu",
198     "net-redynet29.datamarkets.com.ar",
199     "ccs-shiva28.reacciun.net.ve",
200     "7.houston-11.tx.dial-access.att.net",
201     "ingw129-37-120-26.mo.us.ibm.net",
202     "dialup6.austintx.com",
203     "dns2.tpao.gov.tr",
204     "slip129-37-119-194.nc.us.ibm.net",
205     "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
206     "swprd1.innovplace.saskatoon.sk.ca",
207     "bikini.bologna.maraut.it",
208     "node91.subnet159-198-79.baxter.com",
209     "cust19.max5.new-york.ny.ms.uu.net",
210     "balexander.slip.andrew.cmu.edu",
211     "pool029.max2.denver.co.dynip.alter.net",
212     "cust49.max9.new-york.ny.ms.uu.net",
213     "s61.abq-dialin2.hollyberry.com",
214     "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
215     "www.xn--vea.com",
216    // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
217     "www.\\u00C2\\u00A4.com",
218     "www.\\u00C2\\u00A3.com",
219     // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
220     // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
221     //"@",
222     //"\\u002F",
223     //"www.\\u0021.com",
224     //"www.\\u0024.com",
225     //"\\u003f",
226     // These yeild U_IDNA_PROHIBITED_ERROR
227     //"\\u00CF\\u0082.com",
228     //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
229     //"\\u00E2\\u0098\\u00BA.com",
230     "\\u00C3\\u00BC.com",
231 
232 };
233 
234 typedef struct ErrorCases ErrorCases;
235 
236 static const struct ErrorCases{
237 
238     UChar unicode[100];
239     const char *ascii;
240     UErrorCode expected;
241     UBool useSTD3ASCIIRules;
242     UBool testToUnicode;
243     UBool testLabel;
244 } errorCases[] = {
245       {
246 
247         {
248             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
249             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
250             0x070F,/*prohibited*/
251             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
252             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
253             0x0000
254         },
255         "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
256         U_IDNA_PROHIBITED_ERROR,
257         FALSE, FALSE, TRUE
258     },
259 
260     {
261         {
262             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
263             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
264             0x0221, 0x0234/*Unassigned code points*/,
265             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
266             0x0000
267         },
268         "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
269 
270         U_IDNA_UNASSIGNED_ERROR,
271         FALSE, FALSE, TRUE
272     },
273     {
274         {
275             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
276             0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
277             0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
278             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
279             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
280             0x0000
281         },
282         "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
283         U_IDNA_CHECK_BIDI_ERROR,
284         FALSE, FALSE, TRUE
285     },
286     {
287         {
288             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
289             /* labels cannot begin with an HYPHEN */
290             0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
291             0x002E,
292             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
293             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
294             0x0000
295 
296         },
297         "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
298         U_IDNA_STD3_ASCII_RULES_ERROR,
299         TRUE, FALSE, FALSE
300     },
301     {
302         {
303             /* correct ACE-prefix followed by unicode */
304             0x0077, 0x0077, 0x0077, 0x002e, /* www. */
305             0x0078, 0x006e, 0x002d,0x002d,  /* ACE Prefix */
306             0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
307             0x002D,
308             0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
309             0x002e, 0x0063, 0x006f, 0x006d, /* com. */
310             0x0000
311 
312         },
313         /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
314         "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
315         U_IDNA_ACE_PREFIX_ERROR,
316         FALSE, FALSE, FALSE
317     },
318     /* cannot verify U_IDNA_VERIFICATION_ERROR */
319 
320     {
321       {
322         0x0077, 0x0077, 0x0077, 0x002e, /* www. */
323         0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
324         0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
325         0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
326         0x002e, 0x0063, 0x006f, 0x006d, /* com. */
327         0x0000
328       },
329       "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
330       U_IDNA_LABEL_TOO_LONG_ERROR,
331       FALSE, FALSE, TRUE
332     },
333 
334     {
335       {
336         0x0077, 0x0077, 0x0077, 0x002e, /* www. */
337         0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
338         0x002e, 0x0063, 0x006f, 0x006d, /* com. */
339         0x0000
340       },
341       "www.xn--01-tvdmo.com",
342       U_IDNA_CHECK_BIDI_ERROR,
343       FALSE, FALSE, TRUE
344     },
345 
346     {
347       {
348         0x0077, 0x0077, 0x0077, 0x002e, // www.
349         0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
350         0x002e, 0x0063, 0x006f, 0x006d, // com.
351         0x0000
352       },
353       "www.XN--ghbgi278xia.com",
354       U_IDNA_PROHIBITED_ERROR,
355       FALSE, FALSE, TRUE
356     },
357     {
358       {
359         0x0077, 0x0077, 0x0077, 0x002e, // www.
360         0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
361         0x002e, 0x0063, 0x006f, 0x006d, // com.
362         0x0000
363       },
364       "www.-abcde.com",
365       U_IDNA_STD3_ASCII_RULES_ERROR,
366       TRUE, FALSE, FALSE
367     },
368     {
369       {
370         0x0077, 0x0077, 0x0077, 0x002e, // www.
371         0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
372         0x002e, 0x0063, 0x006f, 0x006d, // com.
373         0x0000
374       },
375       "www.abcde-.com",
376       U_IDNA_STD3_ASCII_RULES_ERROR,
377       TRUE, FALSE, FALSE
378     },
379     {
380       {
381         0x0077, 0x0077, 0x0077, 0x002e, // www.
382         0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
383         0x002e, 0x0063, 0x006f, 0x006d, // com.
384         0x0000
385       },
386       "www.abcde@.com",
387       U_IDNA_STD3_ASCII_RULES_ERROR,
388       TRUE, FALSE, FALSE
389     },
390     {
391       {
392         0x0077, 0x0077, 0x0077, 0x002e, // www.
393         // zero length label
394         0x002e, 0x0063, 0x006f, 0x006d, // com.
395         0x0000
396       },
397       "www..com",
398       U_IDNA_ZERO_LENGTH_LABEL_ERROR,
399       TRUE, FALSE, FALSE
400     },
401     {
402       {0},
403       NULL,
404       U_ILLEGAL_ARGUMENT_ERROR,
405       TRUE, TRUE, FALSE
406     }
407 };
408 
409 
410 
411 
412 #define MAX_DEST_SIZE 300
413 
debug(const UChar * src,int32_t srcLength,int32_t options)414 void TestIDNA::debug(const UChar* src, int32_t srcLength, int32_t options){
415     UParseError parseError;
416     UErrorCode transStatus = U_ZERO_ERROR;
417     UErrorCode prepStatus  = U_ZERO_ERROR;
418     NamePrepTransform* trans = NamePrepTransform::createInstance(parseError,transStatus);
419     int32_t prepOptions = (((options & UIDNA_ALLOW_UNASSIGNED) != 0) ? USPREP_ALLOW_UNASSIGNED: 0);
420     UStringPrepProfile* prep = usprep_open(NULL,"uidna",&prepStatus);
421     UChar *transOut=NULL, *prepOut=NULL;
422     int32_t transOutLength=0, prepOutLength=0;
423 
424 
425     transOutLength  = trans->process(src,srcLength,transOut, 0, prepOptions>0, &parseError, transStatus);
426     if( transStatus == U_BUFFER_OVERFLOW_ERROR){
427         transStatus = U_ZERO_ERROR;
428         transOut    = (UChar*) malloc(U_SIZEOF_UCHAR * transOutLength);
429         transOutLength = trans->process(src,srcLength,transOut, transOutLength, prepOptions>0, &parseError, transStatus);
430     }
431 
432     prepOutLength  = usprep_prepare(prep, src, srcLength, prepOut, 0, prepOptions, &parseError, &prepStatus);
433 
434     if( prepStatus == U_BUFFER_OVERFLOW_ERROR){
435         prepStatus = U_ZERO_ERROR;
436         prepOut    = (UChar*) malloc(U_SIZEOF_UCHAR * prepOutLength);
437         prepOutLength  = usprep_prepare(prep, src, srcLength, prepOut, prepOutLength, prepOptions, &parseError, &prepStatus);
438     }
439 
440     if(UnicodeString(transOut,transOutLength)!= UnicodeString(prepOut, prepOutLength)){
441         errln("Failed. Expected: " + prettify(UnicodeString(transOut, transOutLength))
442               + " Got: " + prettify(UnicodeString(prepOut,prepOutLength)));
443     }
444     free(transOut);
445     free(prepOut);
446     delete trans;
447 
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         errln( "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         errln( "%s null terminated source failed. Error: %s\n", 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         errln( "%s null terminated source and options set failed. Error: %s\n",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         errln( "%s with string length. Error: %s\n",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         errln( "%s with string length and options set. Error: %s\n", 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             errln( "%s failed to convert domainNames[%i].Error: %s \n",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             errln( "%s failed to convert domainNames[%i].Error: %s \n",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         errln("%s null terminated source failed. Error: %s\n",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                 errln("%s null terminated source failed\n",testName);
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         errln("%s null terminated source with options set failed. Error: %s\n",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                 errln("%s null terminated source with options set failed\n",testName);
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         errln("%s null terminated source failed. Error: %s\n",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                 errln("%s source with source length failed\n",testName);
1091                 break;
1092             }
1093         }else{
1094             oddLen = func(even,evenLen,odd,MAX_DEST_SIZE,options, &parseError, &status);
1095             if(U_FAILURE(status)){
1096                 errln("%s source with source length failed\n",testName);
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         errln("%s null terminated source with options set failed. Error: %s\n",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                 errln("%s source with source length and options set failed\n",testName);
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                 errln("%s  source with source length and options set failed\n",testName);
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 
runIndexedTest(int32_t index,UBool exec,const char * & name,char * par)1239 void TestIDNA::runIndexedTest( int32_t index, UBool exec, const char* &name, char* par)
1240 {
1241     if (exec) logln((UnicodeString)"TestSuite IDNA API ");
1242     switch (index) {
1243 
1244         case 0: name = "TestToASCII"; if (exec) TestToASCII(); break;
1245         case 1: name = "TestToUnicode"; if (exec) TestToUnicode(); break;
1246         case 2: name = "TestIDNToASCII"; if (exec) TestIDNToASCII(); break;
1247         case 3: name = "TestIDNToUnicode"; if (exec) TestIDNToUnicode(); break;
1248         case 4: name = "TestCompare"; if (exec) TestCompare(); break;
1249         case 5: name = "TestErrorCases"; if (exec) TestErrorCases(); break;
1250         case 6: name = "TestChaining"; if (exec) TestChaining(); break;
1251         case 7: name = "TestRootLabelSeparator"; if(exec) TestRootLabelSeparator(); break;
1252         case 8: name = "TestCompareReferenceImpl"; if(exec) TestCompareReferenceImpl(); break;
1253         case 9: name = "TestDataFile"; if(exec) TestDataFile(); break;
1254         case 10: name = "TestRefIDNA"; if(exec) TestRefIDNA(); break;
1255         case 11: name = "TestIDNAMonkeyTest"; if(exec) TestIDNAMonkeyTest(); break;
1256         case 12:
1257             {
1258                 name = "TestConformanceTestVectors";
1259                 if(exec){
1260                     logln("TestSuite IDNA conf----"); logln();
1261                     IdnaConfTest test;
1262                     callTest(test, par);
1263                 }
1264                 break;
1265             }
1266         default: name = ""; break; /*needed to end loop*/
1267     }
1268 }
TestToASCII()1269 void TestIDNA::TestToASCII(){
1270     testToASCII("uidna_toASCII", uidna_toASCII);
1271 }
TestToUnicode()1272 void TestIDNA::TestToUnicode(){
1273     testToUnicode("uidna_toUnicode", uidna_toUnicode);
1274 }
TestIDNToASCII()1275 void TestIDNA::TestIDNToASCII(){
1276     testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII);
1277 }
TestIDNToUnicode()1278 void TestIDNA::TestIDNToUnicode(){
1279     testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode);
1280 }
TestCompare()1281 void TestIDNA::TestCompare(){
1282     testCompare("uidna_compare",uidna_compare);
1283 }
TestErrorCases()1284 void TestIDNA::TestErrorCases(){
1285     testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII,
1286                     "uidna_IDNToUnicode",uidna_IDNToUnicode);
1287 }
TestRootLabelSeparator()1288 void TestIDNA::TestRootLabelSeparator(){
1289     testRootLabelSeparator( "uidna_compare",uidna_compare,
1290                             "uidna_IDNToASCII", uidna_IDNToASCII,
1291                             "uidna_IDNToUnicode",uidna_IDNToUnicode
1292                             );
1293 }
TestChaining()1294 void TestIDNA::TestChaining(){
1295     testChaining("uidna_toASCII",uidna_toASCII, "uidna_toUnicode", uidna_toUnicode);
1296 }
1297 
1298 
1299 static const int loopCount = 100;
1300 static const int maxCharCount = 20;
1301 static const int maxCodePoint = 0x10ffff;
1302 static uint32_t
randul()1303 randul()
1304 {
1305     static UBool initialized = FALSE;
1306     if (!initialized)
1307     {
1308         srand((unsigned)time(NULL));
1309         initialized = TRUE;
1310     }
1311     // Assume rand has at least 12 bits of precision
1312     uint32_t l = 0;
1313     for (uint32_t i=0; i<sizeof(l); ++i)
1314         ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4);
1315     return l;
1316 }
1317 
1318 /**
1319  * Return a random integer i where 0 <= i < n.
1320  * A special function that gets random codepoints from planes 0,1,2 and 14
1321  */
rand_uni()1322 static int32_t rand_uni()
1323 {
1324    int32_t retVal = (int32_t)(randul()& 0x3FFFF);
1325    if(retVal >= 0x30000){
1326        retVal+=0xB0000;
1327    }
1328    return retVal;
1329 }
1330 
randi(int32_t n)1331 static int32_t randi(int32_t n){
1332     return (int32_t) (randul() % (n+1));
1333 }
1334 
getTestSource(UnicodeString & fillIn)1335 void getTestSource(UnicodeString& fillIn) {
1336     int32_t i = 0;
1337     int32_t charCount = (randi(maxCharCount) + 1);
1338     while (i <charCount ) {
1339         int32_t codepoint = rand_uni();
1340         if(codepoint == 0x0000){
1341             continue;
1342         }
1343         fillIn.append((UChar32)codepoint);
1344         i++;
1345     }
1346 
1347 }
1348 
testCompareReferenceImpl(UnicodeString & src,TestFunc refIDNA,const char * refIDNAName,TestFunc uIDNA,const char * uIDNAName,int32_t options)1349 UnicodeString TestIDNA::testCompareReferenceImpl(UnicodeString& src,
1350                                         TestFunc refIDNA, const char* refIDNAName,
1351                                         TestFunc uIDNA, const char* uIDNAName,
1352                                         int32_t options){
1353 
1354     const UChar* srcUChars = src.getBuffer();
1355     UChar exp[MAX_DEST_SIZE]={0};
1356     int32_t expCap = MAX_DEST_SIZE, expLen=0;
1357     UErrorCode expStatus = U_ZERO_ERROR;
1358     UParseError parseError;
1359 
1360     logln("Comparing "+ UnicodeString(refIDNAName)
1361            + " with "+ UnicodeString(uIDNAName)
1362            +" for input: " + prettify(srcUChars));
1363 
1364     expLen = refIDNA(srcUChars, src.length()-1, exp, expCap,
1365                       options, &parseError, &expStatus);
1366 
1367     UChar got[MAX_DEST_SIZE]={0};
1368     int32_t gotCap = MAX_DEST_SIZE, gotLen=0;
1369     UErrorCode gotStatus = U_ZERO_ERROR;
1370 
1371     gotLen = uIDNA(srcUChars, src.length()-1, got, gotCap,
1372                    options, &parseError, &gotStatus);
1373 
1374     if(expStatus != gotStatus){
1375         errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName)
1376                + " with " + UnicodeString(uIDNAName)
1377                + " Expected: " + UnicodeString(u_errorName(expStatus))
1378                + " Got: " + UnicodeString(u_errorName(gotStatus))
1379                + " for Source: "+ prettify(srcUChars)
1380                + " Options: " + options);
1381         return UnicodeString("");
1382     }
1383 
1384     // now we know that both implementations yielded same error
1385     if(U_SUCCESS(expStatus)){
1386         // compare the outputs if status == U_ZERO_ERROR
1387         if(u_strCompare(exp, expLen, got, gotLen, TRUE) != 0){
1388             errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName)
1389                + " with " + UnicodeString(uIDNAName)
1390                + " Expected: " + prettify(UnicodeString(exp, expLen))
1391                + " Got: " + prettify(UnicodeString(got, gotLen))
1392                + " for Source: "+ prettify(srcUChars)
1393                + " Options: " + options);
1394         }
1395         return UnicodeString(exp, expLen);
1396 
1397     }else{
1398         logln("Got the same error while comparing "
1399             + UnicodeString(refIDNAName)
1400             + " with "+ UnicodeString(uIDNAName)
1401             +" for input: " + prettify(srcUChars));
1402     }
1403     return UnicodeString("");
1404 }
1405 
testCompareReferenceImpl(const UChar * src,int32_t srcLen)1406 void TestIDNA::testCompareReferenceImpl(const UChar* src, int32_t srcLen){
1407     UnicodeString label(src,srcLen);
1408     label.append((UChar)0x0000);
1409 
1410     //test idnaref_toASCII and idnare
1411     UnicodeString asciiLabel = testCompareReferenceImpl(label,
1412                                                       idnaref_toASCII, "idnaref_toASCII",
1413                                                       uidna_toASCII, "uidna_toASCII",
1414                                                       UIDNA_ALLOW_UNASSIGNED);
1415     testCompareReferenceImpl(label,
1416                               idnaref_toASCII, "idnaref_toASCII",
1417                               uidna_toASCII, "uidna_toASCII",
1418                               UIDNA_DEFAULT);
1419     testCompareReferenceImpl(label,
1420                               idnaref_toASCII, "idnaref_toASCII",
1421                               uidna_toASCII, "uidna_toASCII",
1422                               UIDNA_USE_STD3_RULES);
1423     testCompareReferenceImpl(label,
1424                               idnaref_toASCII, "idnaref_toASCII",
1425                               uidna_toASCII, "uidna_toASCII",
1426                               UIDNA_USE_STD3_RULES | UIDNA_ALLOW_UNASSIGNED);
1427 
1428     if(asciiLabel.length()!=0){
1429         asciiLabel.append((UChar)0x0000);
1430 
1431         // test toUnciode
1432         testCompareReferenceImpl(asciiLabel,
1433                                   idnaref_toUnicode, "idnaref_toUnicode",
1434                                   uidna_toUnicode, "uidna_toUnicode",
1435                                   UIDNA_ALLOW_UNASSIGNED);
1436         testCompareReferenceImpl(asciiLabel,
1437                                   idnaref_toUnicode, "idnaref_toUnicode",
1438                                   uidna_toUnicode, "uidna_toUnicode",
1439                                   UIDNA_DEFAULT);
1440         testCompareReferenceImpl(asciiLabel,
1441                                   idnaref_toUnicode, "idnaref_toUnicode",
1442                                   uidna_toUnicode, "uidna_toUnicode",
1443                                   UIDNA_USE_STD3_RULES);
1444         testCompareReferenceImpl(asciiLabel,
1445                                   idnaref_toUnicode, "idnaref_toUnicode",
1446                                   uidna_toUnicode, "uidna_toUnicode",
1447                                   UIDNA_USE_STD3_RULES | UIDNA_ALLOW_UNASSIGNED);
1448     }
1449 
1450 }
1451 const char* failures[] ={
1452     "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1453     "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1454 };
1455 
TestIDNAMonkeyTest()1456 void TestIDNA::TestIDNAMonkeyTest(){
1457     UnicodeString source;
1458     UErrorCode status = U_ZERO_ERROR;
1459     int i;
1460 
1461     getInstance(status);    // Init prep
1462     if (U_FAILURE(status)) {
1463         errln("Test could not initialize. Got %s", u_errorName(status));
1464         return;
1465     }
1466 
1467     for(i=0; i<loopCount; i++){
1468         source.truncate(0);
1469         getTestSource(source);
1470         source.append((UChar)0x0000);
1471         const UChar* src = source.getBuffer();
1472         testCompareReferenceImpl(src,source.length()-1);
1473         testCompareReferenceImpl(src,source.length()-1);
1474     }
1475 
1476     /* for debugging */
1477     for (i=0; i<(int)(sizeof(failures)/sizeof(failures[0])); i++){
1478         source.truncate(0);
1479         source.append( failures[i] );
1480         source = source.unescape();
1481         source.append((UChar)0x0000);
1482         const UChar *src = source.getBuffer();
1483         testCompareReferenceImpl(src,source.length()-1);
1484         //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1485     }
1486 
1487 
1488     source.truncate(0);
1489     source.append("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C");
1490     debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1491 
1492     { // test deletion of code points
1493         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");
1494         source = source.unescape();
1495         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");
1496         expected = expected.unescape();
1497         UnicodeString ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1498         ascii.append((UChar)0x0000);
1499         testAPI(source.getBuffer(),ascii.getBuffer(), "uidna_toASCII", FALSE, U_ZERO_ERROR, TRUE, TRUE, uidna_toASCII);
1500 
1501         testAPI(source.getBuffer(),ascii.getBuffer(), "idnaref_toASCII", FALSE, U_ZERO_ERROR, TRUE, TRUE, idnaref_toASCII);
1502 
1503         testCompareReferenceImpl(source.getBuffer(), source.length()-1);
1504     }
1505 
1506 }
1507 
TestCompareReferenceImpl()1508 void TestIDNA::TestCompareReferenceImpl(){
1509 
1510     UChar src [2] = {0,0};
1511     int32_t srcLen = 0;
1512 
1513 
1514     for(int32_t i = 0x40000 ; i< 0x10ffff; i++){
1515         if(quick==TRUE && i> 0x1FFFF){
1516             return;
1517         }
1518         if(i >= 0x30000 && i <= 0xF0000){
1519            i+=0xB0000;
1520         }
1521         if(i>0xFFFF){
1522            src[0] = U16_LEAD(i);
1523            src[1] = U16_TRAIL(i);
1524            srcLen =2;
1525         }else{
1526             src[0] = (UChar)i;
1527             src[1] = 0;
1528             srcLen = 1;
1529         }
1530         testCompareReferenceImpl(src, srcLen);
1531     }
1532 }
1533 
TestRefIDNA()1534 void TestIDNA::TestRefIDNA(){
1535     UErrorCode status = U_ZERO_ERROR;
1536     getInstance(status);    // Init prep
1537     if (U_FAILURE(status)) {
1538         errln("Test could not initialize. Got %s", u_errorName(status));
1539         return;
1540     }
1541 
1542     testToASCII("idnaref_toASCII", idnaref_toASCII);
1543     testToUnicode("idnaref_toUnicode", idnaref_toUnicode);
1544     testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII);
1545     testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode);
1546     testCompare("idnaref_compare",idnaref_compare);
1547     testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII,
1548                     "idnaref_IDNToUnicode",idnaref_IDNToUnicode);
1549     testChaining("idnaref_toASCII",idnaref_toASCII, "idnaref_toUnicode", idnaref_toUnicode);
1550 
1551     testRootLabelSeparator( "idnaref_compare",idnaref_compare,
1552                             "idnaref_IDNToASCII", idnaref_IDNToASCII,
1553                             "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1554                             );
1555     testChaining("idnaref_toASCII",idnaref_toASCII, "idnaref_toUnicode", idnaref_toUnicode);
1556 }
1557 
1558 
TestDataFile()1559 void TestIDNA::TestDataFile(){
1560      testData(*this);
1561 }
~TestIDNA()1562 TestIDNA::~TestIDNA(){
1563     if(gPrep!=NULL){
1564         delete gPrep;
1565         gPrep = NULL;
1566     }
1567 }
1568 
1569 NamePrepTransform* TestIDNA::gPrep = NULL;
1570 
getInstance(UErrorCode & status)1571 NamePrepTransform* TestIDNA::getInstance(UErrorCode& status){
1572     if(TestIDNA::gPrep == NULL){
1573         UParseError parseError;
1574         TestIDNA::gPrep = NamePrepTransform::createInstance(parseError, status);
1575         if(TestIDNA::gPrep ==NULL){
1576            //status = U_MEMORY_ALLOCATION_ERROR;
1577            return NULL;
1578         }
1579     }
1580     return TestIDNA::gPrep;
1581 
1582 }
1583 #endif /* #if !UCONFIG_NO_IDNA */
1584