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