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