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