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