1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 *******************************************************************************
6 * Copyright (C) 2003-2016, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 *******************************************************************************
10 * file name: testidna.cpp
12 * tab size: 8 (not used)
15 * created on: 2003feb1
16 * created by: Ram Viswanadha
19 #include "unicode/utypes.h"
21 #if !UCONFIG_NO_IDNA && !UCONFIG_NO_TRANSLITERATION
27 #include "unicode/localpointer.h"
28 #include "unicode/ustring.h"
29 #include "unicode/usprep.h"
30 #include "unicode/uniset.h"
31 #include "unicode/utf16.h"
36 #include "unicode/putil.h"
39 static const UChar unicodeIn
[][41] ={
41 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
42 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
45 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
49 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
50 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
51 0x0065, 0x0073, 0x006B, 0x0079, 0x0000
54 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
55 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
56 0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
59 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
60 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
61 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
62 0x0939, 0x0948, 0x0902, 0x0000
65 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
66 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
71 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
72 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
73 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
77 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
78 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
79 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
83 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
84 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
85 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
86 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
87 0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
90 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
94 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
95 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
96 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
97 0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
100 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
103 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
104 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
105 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
108 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
109 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
110 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
113 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
116 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
117 0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
120 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
124 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
126 // test non-BMP code points
128 0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
129 0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
133 0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
134 0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
140 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
144 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
149 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
150 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
151 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
152 0x0441, 0x0441, 0x043a, 0x0438
160 static const char *asciiIn
[] = {
161 "xn--egbpdaj6bu4bxfgehfvwxn",
162 "xn--ihqwcrb4cv8a8dqg056pqjye",
163 "xn--Proprostnemluvesky-uyb24dma41a",
164 "xn--4dbcagdahymbxekheh6e0a7fei0b",
165 "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
166 "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
167 /* "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
168 "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
169 "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
170 "xn--ihqwctvzc91f659drss3x8bo0yb",
171 "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
172 "xn--3B-ww4c5e180e575a65lsy2b",
173 "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
174 "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
175 "xn--2-u9tlzr9756bt3uc0v",
176 "xn--MajiKoi5-783gue6qz075azm5e",
177 "xn--de-jg4avhby1noc0d",
178 "xn--d9juau41awczczp",
180 "XN--db8CBHEJLGH4E0AL",
181 "xn--hxargifdar", // Greek
182 "xn--bonusaa-5bb1da", // Maltese
183 "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
187 static const char *domainNames
[] = {
188 "slip129-37-118-146.nc.us.ibm.net",
189 "saratoga.pe.utexas.edu",
190 "dial-120-45.ots.utexas.edu",
191 "woo-085.dorms.waller.net",
192 "hd30-049.hil.compuserve.com",
193 "pem203-31.pe.ttu.edu",
194 "56K-227.MaxTNT3.pdq.net",
195 "dial-36-2.ots.utexas.edu",
196 "slip129-37-23-152.ga.us.ibm.net",
197 "ts45ip119.cadvision.com",
198 "sdn-ts-004txaustP05.dialsprint.net",
199 "bar-tnt1s66.erols.com",
200 "101.st-louis-15.mo.dial-access.att.net",
202 "dial-13-2.ots.utexas.edu",
203 "net-redynet29.datamarkets.com.ar",
204 "ccs-shiva28.reacciun.net.ve",
205 "7.houston-11.tx.dial-access.att.net",
206 "ingw129-37-120-26.mo.us.ibm.net",
207 "dialup6.austintx.com",
209 "slip129-37-119-194.nc.us.ibm.net",
210 "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
211 "swprd1.innovplace.saskatoon.sk.ca",
212 "bikini.bologna.maraut.it",
213 "node91.subnet159-198-79.baxter.com",
214 "cust19.max5.new-york.ny.ms.uu.net",
215 "balexander.slip.andrew.cmu.edu",
216 "pool029.max2.denver.co.dynip.alter.net",
217 "cust49.max9.new-york.ny.ms.uu.net",
218 "s61.abq-dialin2.hollyberry.com",
219 "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
221 // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
222 "www.\\u00C2\\u00A4.com",
223 "www.\\u00C2\\u00A3.com",
224 // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
225 // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
231 // These yeild U_IDNA_PROHIBITED_ERROR
232 //"\\u00CF\\u0082.com",
233 //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
234 //"\\u00E2\\u0098\\u00BA.com",
235 "\\u00C3\\u00BC.com",
239 typedef struct ErrorCases ErrorCases
;
241 static const struct ErrorCases
{
246 UBool useSTD3ASCIIRules
;
253 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
254 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
255 0x070F,/*prohibited*/
256 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
257 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
260 "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
261 U_IDNA_PROHIBITED_ERROR
,
267 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
268 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
269 0x0221, 0x0234/*Unassigned code points*/,
270 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
273 "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
275 U_IDNA_UNASSIGNED_ERROR
,
280 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
281 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
282 0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
283 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
284 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
287 "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
288 U_IDNA_CHECK_BIDI_ERROR
,
293 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
294 /* labels cannot begin with an HYPHEN */
295 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
297 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
298 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
302 "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
303 U_IDNA_STD3_ASCII_RULES_ERROR
,
308 /* correct ACE-prefix followed by unicode */
309 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
310 0x0078, 0x006e, 0x002d,0x002d, /* ACE Prefix */
311 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
313 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
314 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
318 /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
319 "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
320 U_IDNA_ACE_PREFIX_ERROR
,
323 /* cannot verify U_IDNA_VERIFICATION_ERROR */
327 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
328 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
329 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
330 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
331 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
334 "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
335 U_IDNA_LABEL_TOO_LONG_ERROR
,
341 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
342 0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
343 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
346 "www.xn--01-tvdmo.com",
347 U_IDNA_CHECK_BIDI_ERROR
,
353 0x0077, 0x0077, 0x0077, 0x002e, // www.
354 0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
355 0x002e, 0x0063, 0x006f, 0x006d, // com.
358 "www.XN--ghbgi278xia.com",
359 U_IDNA_PROHIBITED_ERROR
,
364 0x0077, 0x0077, 0x0077, 0x002e, // www.
365 0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
366 0x002e, 0x0063, 0x006f, 0x006d, // com.
370 U_IDNA_STD3_ASCII_RULES_ERROR
,
375 0x0077, 0x0077, 0x0077, 0x002e, // www.
376 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
377 0x002e, 0x0063, 0x006f, 0x006d, // com.
381 U_IDNA_STD3_ASCII_RULES_ERROR
,
386 0x0077, 0x0077, 0x0077, 0x002e, // www.
387 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
388 0x002e, 0x0063, 0x006f, 0x006d, // com.
392 U_IDNA_STD3_ASCII_RULES_ERROR
,
397 0x0077, 0x0077, 0x0077, 0x002e, // www.
399 0x002e, 0x0063, 0x006f, 0x006d, // com.
403 U_IDNA_ZERO_LENGTH_LABEL_ERROR
,
409 U_ILLEGAL_ARGUMENT_ERROR
,
417 #define MAX_DEST_SIZE 300
419 void TestIDNA::debug(const UChar
* src
, int32_t srcLength
, int32_t options
){
420 UParseError parseError
;
421 UErrorCode transStatus
= U_ZERO_ERROR
;
422 UErrorCode prepStatus
= U_ZERO_ERROR
;
423 NamePrepTransform
* trans
= NamePrepTransform::createInstance(parseError
,transStatus
);
424 int32_t prepOptions
= (((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0);
425 LocalUStringPrepProfilePointer
prep(usprep_openByType(USPREP_RFC3491_NAMEPREP
,&prepStatus
));
426 UChar
*transOut
=NULL
, *prepOut
=NULL
;
427 int32_t transOutLength
=0, prepOutLength
=0;
430 transOutLength
= trans
->process(src
,srcLength
,transOut
, 0, prepOptions
>0, &parseError
, transStatus
);
431 if( transStatus
== U_BUFFER_OVERFLOW_ERROR
){
432 transStatus
= U_ZERO_ERROR
;
433 transOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* transOutLength
);
434 transOutLength
= trans
->process(src
,srcLength
,transOut
, transOutLength
, prepOptions
>0, &parseError
, transStatus
);
437 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, 0, prepOptions
, &parseError
, &prepStatus
);
439 if( prepStatus
== U_BUFFER_OVERFLOW_ERROR
){
440 prepStatus
= U_ZERO_ERROR
;
441 prepOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* prepOutLength
);
442 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, prepOutLength
, prepOptions
, &parseError
, &prepStatus
);
445 if(UnicodeString(transOut
,transOutLength
)!= UnicodeString(prepOut
, prepOutLength
)){
446 errln("Failed. Expected: " + prettify(UnicodeString(transOut
, transOutLength
))
447 + " Got: " + prettify(UnicodeString(prepOut
,prepOutLength
)));
454 void TestIDNA::testAPI(const UChar
* src
, const UChar
* expected
, const char* testName
,
455 UBool useSTD3ASCIIRules
,UErrorCode expectedStatus
,
456 UBool doCompare
, UBool testUnassigned
, TestFunc func
, UBool testSTD3ASCIIRules
){
458 UErrorCode status
= U_ZERO_ERROR
;
459 UChar destStack
[MAX_DEST_SIZE
];
462 int32_t expectedLen
= (expected
!= NULL
) ? u_strlen(expected
) : 0;
463 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
464 UParseError parseError
;
469 tSrcLen
= u_strlen(src
);
470 tSrc
=(UChar
*) malloc( U_SIZEOF_UCHAR
* tSrcLen
);
471 memcpy(tSrc
,src
,tSrcLen
* U_SIZEOF_UCHAR
);
474 // test null-terminated source and return value of number of UChars required
475 destLen
= func(src
,-1,NULL
,0,options
, &parseError
, &status
);
476 if (status
== U_FILE_ACCESS_ERROR
) {
477 dataerrln("U_FILE_ACCESS_ERROR. Skipping the remainder of this test.");
480 if(status
== U_BUFFER_OVERFLOW_ERROR
){
481 status
= U_ZERO_ERROR
; // reset error code
482 if(destLen
+1 < MAX_DEST_SIZE
){
484 destLen
= func(src
,-1,dest
,destLen
+1,options
, &parseError
, &status
);
485 // TODO : compare output with expected
486 if(U_SUCCESS(status
) && expectedStatus
!= U_IDNA_STD3_ASCII_RULES_ERROR
&& (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
487 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source. Expected : "
488 + prettify(UnicodeString(expected
,expectedLen
))
489 + " Got: " + prettify(UnicodeString(dest
,destLen
))
493 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
497 if(status
!= expectedStatus
){
498 errcheckln(status
, "Did not get the expected error for "+
499 UnicodeString(testName
)+
500 " null terminated source. Expected: " +UnicodeString(u_errorName(expectedStatus
))
501 + " Got: "+ UnicodeString(u_errorName(status
))
502 + " Source: " + prettify(UnicodeString(src
))
508 status
= U_ZERO_ERROR
;
509 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
510 if(status
== U_BUFFER_OVERFLOW_ERROR
){
511 status
= U_ZERO_ERROR
; // reset error code
512 if(destLen
+1 < MAX_DEST_SIZE
){
514 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
515 // TODO : compare output with expected
516 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
517 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
518 errln("Did not get the expected result for "+UnicodeString(testName
) +
519 " null terminated source "+ prettify(src
) +
520 " with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
))+
521 "Got: " + prettify(UnicodeString(dest
,destLen
)));
523 debug(src
,-1,options
| UIDNA_ALLOW_UNASSIGNED
);
527 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
530 //testing query string
531 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
532 errln( "Did not get the expected error for "+
533 UnicodeString(testName
)+
534 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
535 + " Got: "+ UnicodeString(u_errorName(status
))
536 + " Source: " + prettify(UnicodeString(src
))
541 status
= U_ZERO_ERROR
;
543 // test source with lengthand return value of number of UChars required
544 destLen
= func(tSrc
, tSrcLen
, NULL
,0,options
, &parseError
, &status
);
545 if(status
== U_BUFFER_OVERFLOW_ERROR
){
546 status
= U_ZERO_ERROR
; // reset error code
547 if(destLen
+1 < MAX_DEST_SIZE
){
549 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
, &parseError
, &status
);
550 // TODO : compare output with expected
551 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
552 errln("Did not get the expected result for %s with source length.\n",testName
);
555 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
559 if(status
!= expectedStatus
){
560 errln( "Did not get the expected error for "+
561 UnicodeString(testName
)+
562 " with source length. Expected: " +UnicodeString(u_errorName(expectedStatus
))
563 + " Got: "+ UnicodeString(u_errorName(status
))
564 + " Source: " + prettify(UnicodeString(src
))
568 status
= U_ZERO_ERROR
;
570 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
572 if(status
== U_BUFFER_OVERFLOW_ERROR
){
573 status
= U_ZERO_ERROR
; // reset error code
574 if(destLen
+1 < MAX_DEST_SIZE
){
576 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
577 // TODO : compare output with expected
578 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
579 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
582 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
585 //testing query string
586 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
587 errln( "Did not get the expected error for "+
588 UnicodeString(testName
)+
589 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
590 + " Got: "+ UnicodeString(u_errorName(status
))
591 + " Source: " + prettify(UnicodeString(src
))
596 status
= U_ZERO_ERROR
;
597 if(testSTD3ASCIIRules
==TRUE
){
598 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
599 if(status
== U_BUFFER_OVERFLOW_ERROR
){
600 status
= U_ZERO_ERROR
; // reset error code
601 if(destLen
+1 < MAX_DEST_SIZE
){
603 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
604 // TODO : compare output with expected
605 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
606 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
607 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
)));
611 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
614 //testing query string
615 if(status
!= expectedStatus
){
616 errln( "Did not get the expected error for "+
617 UnicodeString(testName
)+
618 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
619 + " Got: "+ UnicodeString(u_errorName(status
))
620 + " Source: " + prettify(UnicodeString(src
))
624 status
= U_ZERO_ERROR
;
626 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
628 if(status
== U_BUFFER_OVERFLOW_ERROR
){
629 status
= U_ZERO_ERROR
; // reset error code
630 if(destLen
+1 < MAX_DEST_SIZE
){
632 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
633 // TODO : compare output with expected
634 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
635 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
638 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
641 //testing query string
642 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
643 errln( "Did not get the expected error for "+
644 UnicodeString(testName
)+
645 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
646 + " Got: "+ UnicodeString(u_errorName(status
))
647 + " Source: " + prettify(UnicodeString(src
))
654 void TestIDNA::testCompare(const UChar
* s1
, int32_t s1Len
,
655 const UChar
* s2
, int32_t s2Len
,
656 const char* testName
, CompareFunc func
,
659 UErrorCode status
= U_ZERO_ERROR
;
660 int32_t retVal
= func(s1
,-1,s2
,-1,UIDNA_DEFAULT
,&status
);
662 if(isEqual
==TRUE
&& retVal
!=0){
663 errln("Did not get the expected result for %s with null termniated strings.\n",testName
);
665 if(U_FAILURE(status
)){
666 errcheckln(status
, "%s null terminated source failed. Error: %s", testName
,u_errorName(status
));
669 status
= U_ZERO_ERROR
;
670 retVal
= func(s1
,-1,s2
,-1,UIDNA_ALLOW_UNASSIGNED
,&status
);
672 if(isEqual
==TRUE
&& retVal
!=0){
673 errln("Did not get the expected result for %s with null termniated strings with options set.\n", testName
);
675 if(U_FAILURE(status
)){
676 errcheckln(status
, "%s null terminated source and options set failed. Error: %s",testName
, u_errorName(status
));
679 status
= U_ZERO_ERROR
;
680 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_DEFAULT
,&status
);
682 if(isEqual
==TRUE
&& retVal
!=0){
683 errln("Did not get the expected result for %s with string length.\n",testName
);
685 if(U_FAILURE(status
)){
686 errcheckln(status
, "%s with string length. Error: %s",testName
, u_errorName(status
));
689 status
= U_ZERO_ERROR
;
690 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_ALLOW_UNASSIGNED
,&status
);
692 if(isEqual
==TRUE
&& retVal
!=0){
693 errln("Did not get the expected result for %s with string length and options set.\n",testName
);
695 if(U_FAILURE(status
)){
696 errcheckln(status
, "%s with string length and options set. Error: %s", u_errorName(status
), testName
);
700 void TestIDNA::testToASCII(const char* testName
, TestFunc func
){
703 UChar buf
[MAX_DEST_SIZE
];
705 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
706 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
707 testAPI(unicodeIn
[i
], buf
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
712 void TestIDNA::testToUnicode(const char* testName
, TestFunc func
){
715 UChar buf
[MAX_DEST_SIZE
];
717 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
718 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
719 testAPI(buf
,unicodeIn
[i
],testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
724 void TestIDNA::testIDNToUnicode(const char* testName
, TestFunc func
){
726 UChar buf
[MAX_DEST_SIZE
];
727 UChar expected
[MAX_DEST_SIZE
];
728 UErrorCode status
= U_ZERO_ERROR
;
730 UParseError parseError
;
731 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
732 bufLen
= (int32_t)strlen(domainNames
[i
]);
733 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
734 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
735 if(U_FAILURE(status
)){
736 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
, i
, u_errorName(status
));
739 testAPI(buf
,expected
,testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
740 //test toUnicode with all labels in the string
741 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
742 if(U_FAILURE(status
)){
743 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
750 void TestIDNA::testIDNToASCII(const char* testName
, TestFunc func
){
752 UChar buf
[MAX_DEST_SIZE
];
753 UChar expected
[MAX_DEST_SIZE
];
754 UErrorCode status
= U_ZERO_ERROR
;
756 UParseError parseError
;
757 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
758 bufLen
= (int32_t)strlen(domainNames
[i
]);
759 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
760 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
761 if(U_FAILURE(status
)){
762 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
,i
, u_errorName(status
));
765 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
766 //test toASCII with all labels in the string
767 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, FALSE
, TRUE
, func
);
768 if(U_FAILURE(status
)){
769 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
776 void TestIDNA::testCompare(const char* testName
, CompareFunc func
){
780 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
781 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x0000};
782 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
784 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
786 uni0
.append(unicodeIn
[0]);
788 uni0
.append((UChar
)0x0000);
790 uni1
.append(unicodeIn
[1]);
792 uni1
.append((UChar
)0x0000);
794 ascii0
.append(asciiIn
[0]);
796 ascii0
.append((UChar
)0x0000);
798 ascii1
.append(asciiIn
[1]);
800 ascii1
.append((UChar
)0x0000);
802 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
804 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
807 // for every entry in unicodeIn array
808 // prepend www. and append .com
810 source
.append(unicodeIn
[i
]);
812 source
.append((UChar
)0x0000);
813 // a) compare it with itself
814 const UChar
* src
= source
.getBuffer();
815 int32_t srcLen
= u_strlen(src
); //subtract null
817 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
, TRUE
);
819 // b) compare it with asciiIn equivalent
820 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
822 // c) compare it with unicodeIn not equivalent
824 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
826 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
828 // d) compare it with asciiIn not equivalent
830 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
832 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
841 getNextSeperator(UChar
*src
,int32_t srcLength
,
847 *limit
= src
+ i
; // point to null
851 *limit
= src
+ (i
+1); // go past the delimiter
855 // we have not found the delimiter
857 *limit
= src
+srcLength
;
862 for(i
=0;i
<srcLength
;i
++){
864 *limit
= src
+ (i
+1); // go past the delimiter
868 // we have not found the delimiter
870 *limit
= src
+srcLength
;
876 void printPunycodeOutput(){
878 UChar dest
[MAX_DEST_SIZE
];
879 int32_t destCapacity
=MAX_DEST_SIZE
;
883 UBool caseFlags
[MAX_DEST_SIZE
];
885 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
886 ErrorCases errorCase
= errorCases
[i
];
887 UErrorCode status
= U_ZERO_ERROR
;
888 start
= errorCase
.unicode
;
889 int32_t srcLen
= u_strlen(start
);
890 labelLen
= getNextSeperator(start
,srcLen
,&limit
);
892 labelLen
=getNextSeperator(start
,srcLen
-labelLen
,&limit
);
893 int32_t destLen
= u_strToPunycode(dest
,destCapacity
,start
,labelLen
,caseFlags
, &status
);
894 if(U_FAILURE(status
)){
895 printf("u_strToPunycode failed for index %i\n",i
);
898 for(int32_t j
=0; j
<destLen
; j
++){
899 printf("%c",(char)dest
[j
]);
906 void TestIDNA::testErrorCases(const char* IDNToASCIIName
, TestFunc IDNToASCII
,
907 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
908 UChar buf
[MAX_DEST_SIZE
];
911 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
912 ErrorCases errorCase
= errorCases
[i
];
914 if(errorCase
.ascii
!= NULL
){
915 bufLen
= (int32_t)strlen(errorCase
.ascii
);
916 u_charsToUChars(errorCase
.ascii
,buf
, bufLen
+1);
919 memset(buf
,0,U_SIZEOF_UCHAR
*MAX_DEST_SIZE
);
922 if(errorCase
.unicode
[0]!=0){
923 src
= errorCase
.unicode
;
927 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
928 errorCase
.expected
, TRUE
, TRUE
, IDNToASCII
);
929 if(errorCase
.testLabel
==TRUE
){
931 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
932 errorCase
.expected
, FALSE
,TRUE
, IDNToASCII
);
934 if(errorCase
.testToUnicode
==TRUE
){
935 testAPI((src
==NULL
)? NULL
: buf
,src
,
936 IDNToUnicodeName
, errorCase
.useSTD3ASCIIRules
,
937 errorCase
.expected
, TRUE
, TRUE
, IDNToUnicode
);
944 void TestIDNA::testConformance(const char* toASCIIName, TestFunc toASCII,
945 const char* IDNToASCIIName, TestFunc IDNToASCII,
946 const char* IDNToUnicodeName, TestFunc IDNToUnicode,
947 const char* toUnicodeName, TestFunc toUnicode){
948 UChar src[MAX_DEST_SIZE];
950 UChar expected[MAX_DEST_SIZE];
951 int32_t expectedLen = 0;
952 for(int32_t i=0;i< UPRV_LENGTHOF(conformanceTestCases);i++){
953 const char* utf8Chars1 = conformanceTestCases[i].in;
954 int32_t utf8Chars1Len = (int32_t)strlen(utf8Chars1);
955 const char* utf8Chars2 = conformanceTestCases[i].out;
956 int32_t utf8Chars2Len = (utf8Chars2 == NULL) ? 0 : (int32_t)strlen(utf8Chars2);
958 UErrorCode status = U_ZERO_ERROR;
959 u_strFromUTF8(src,MAX_DEST_SIZE,&srcLen,utf8Chars1,utf8Chars1Len,&status);
960 if(U_FAILURE(status)){
961 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
964 if(utf8Chars2 != NULL){
965 u_strFromUTF8(expected,MAX_DEST_SIZE,&expectedLen,utf8Chars2,utf8Chars2Len, &status);
966 if(U_FAILURE(status)){
967 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
972 if(conformanceTestCases[i].expectedStatus != U_ZERO_ERROR){
974 testAPI(src,expected,
975 IDNToASCIIName, FALSE,
976 conformanceTestCases[i].expectedStatus,
978 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
981 testAPI(src,expected,
983 conformanceTestCases[i].expectedStatus, TRUE,
984 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
989 IDNToUnicodeName, FALSE,
990 conformanceTestCases[i].expectedStatus, TRUE, TRUE, IDNToUnicode);
992 toUnicodeName, FALSE,
993 conformanceTestCases[i].expectedStatus, TRUE, TRUE, toUnicode);
999 // test and ascertain
1000 // func(func(func(src))) == func(src)
1001 void TestIDNA::testChaining(const UChar
* src
,int32_t numIterations
,const char* testName
,
1002 UBool useSTD3ASCIIRules
, UBool caseInsensitive
, TestFunc func
){
1003 UChar even
[MAX_DEST_SIZE
];
1004 UChar odd
[MAX_DEST_SIZE
];
1005 UChar expected
[MAX_DEST_SIZE
];
1006 int32_t i
=0,evenLen
=0,oddLen
=0,expectedLen
=0;
1007 UErrorCode status
= U_ZERO_ERROR
;
1008 int32_t srcLen
= u_strlen(src
);
1009 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
1010 UParseError parseError
;
1012 // test null-terminated source
1013 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
, options
, &parseError
, &status
);
1014 if(U_FAILURE(status
)){
1015 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1017 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1018 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1019 for(;i
<=numIterations
; i
++){
1021 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1022 if(U_FAILURE(status
)){
1023 errcheckln(status
, "%s null terminated source failed - %s",testName
, u_errorName(status
));
1027 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1028 if(U_FAILURE(status
)){
1029 errln("%s null terminated source failed\n",testName
);
1034 if(caseInsensitive
==TRUE
){
1035 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1036 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1038 errln("Chaining for %s null terminated source failed\n",testName
);
1041 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1042 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1044 errln("Chaining for %s null terminated source failed\n",testName
);
1048 // test null-terminated source
1049 status
= U_ZERO_ERROR
;
1050 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1051 if(U_FAILURE(status
)){
1052 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1054 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1055 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1056 for(;i
<=numIterations
; i
++){
1058 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1059 if(U_FAILURE(status
)){
1060 errcheckln(status
, "%s null terminated source with options set failed - %s",testName
, u_errorName(status
));
1064 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1065 if(U_FAILURE(status
)){
1066 errln("%s null terminated source with options set failed\n",testName
);
1071 if(caseInsensitive
==TRUE
){
1072 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1073 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1075 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1078 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1079 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1081 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1086 // test source with length
1087 status
= U_ZERO_ERROR
;
1088 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1089 if(U_FAILURE(status
)){
1090 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1092 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1093 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1094 for(;i
<=numIterations
; i
++){
1096 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1097 if(U_FAILURE(status
)){
1098 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1102 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1103 if(U_FAILURE(status
)){
1104 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1109 if(caseInsensitive
==TRUE
){
1110 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1111 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1113 errln("Chaining for %s source with source length failed\n",testName
);
1116 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1117 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1119 errln("Chaining for %s source with source length failed\n",testName
);
1122 status
= U_ZERO_ERROR
;
1123 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1124 if(U_FAILURE(status
)){
1125 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1127 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1128 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1129 for(;i
<=numIterations
; i
++){
1131 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1132 if(U_FAILURE(status
)){
1133 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1137 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1138 if(U_FAILURE(status
)){
1139 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1144 if(caseInsensitive
==TRUE
){
1145 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1146 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1148 errln("Chaining for %s source with source length and options set failed\n",testName
);
1151 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1152 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1154 errln("Chaining for %s source with source length and options set failed\n",testName
);
1158 void TestIDNA::testChaining(const char* toASCIIName
, TestFunc toASCII
,
1159 const char* toUnicodeName
, TestFunc toUnicode
){
1161 UChar buf
[MAX_DEST_SIZE
];
1163 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
1164 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
1165 testChaining(buf
,5,toUnicodeName
, FALSE
, FALSE
, toUnicode
);
1167 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1168 testChaining(unicodeIn
[i
], 5,toASCIIName
, FALSE
, TRUE
, toASCII
);
1173 void TestIDNA::testRootLabelSeparator(const char* testName
, CompareFunc func
,
1174 const char* IDNToASCIIName
, TestFunc IDNToASCII
,
1175 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
1179 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1180 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x002E, /* root label separator */0x0000};
1181 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1183 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
1185 uni0
.append(unicodeIn
[0]);
1187 uni0
.append((UChar
)0x0000);
1189 uni1
.append(unicodeIn
[1]);
1191 uni1
.append((UChar
)0x0000);
1193 ascii0
.append(asciiIn
[0]);
1195 ascii0
.append((UChar
)0x0000);
1197 ascii1
.append(asciiIn
[1]);
1199 ascii1
.append((UChar
)0x0000);
1201 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1203 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
1206 // for every entry in unicodeIn array
1207 // prepend www. and append .com
1209 source
.append(unicodeIn
[i
]);
1211 source
.append((UChar
)0x0000);
1213 const UChar
* src
= source
.getBuffer();
1214 int32_t srcLen
= u_strlen(src
); //subtract null
1216 // b) compare it with asciiIn equivalent
1217 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
1219 // a) compare it with itself
1220 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
,TRUE
);
1223 // IDNToASCII comparison
1224 testAPI(src
,buf
,IDNToASCIIName
,FALSE
,U_ZERO_ERROR
,TRUE
, TRUE
, IDNToASCII
);
1225 // IDNToUnicode comparison
1226 testAPI(buf
,src
,IDNToUnicodeName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, IDNToUnicode
);
1228 // c) compare it with unicodeIn not equivalent
1230 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
1232 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
1234 // d) compare it with asciiIn not equivalent
1236 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
1238 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
1243 //---------------------------------------------
1245 //---------------------------------------------
1247 extern IntlTest
*createUTS46Test();
1249 void TestIDNA::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* par
)
1251 if (exec
) logln((UnicodeString
)"TestSuite IDNA API ");
1254 case 0: name
= "TestToASCII"; if (exec
) TestToASCII(); break;
1255 case 1: name
= "TestToUnicode"; if (exec
) TestToUnicode(); break;
1256 case 2: name
= "TestIDNToASCII"; if (exec
) TestIDNToASCII(); break;
1257 case 3: name
= "TestIDNToUnicode"; if (exec
) TestIDNToUnicode(); break;
1258 case 4: name
= "TestCompare"; if (exec
) TestCompare(); break;
1259 case 5: name
= "TestErrorCases"; if (exec
) TestErrorCases(); break;
1260 case 6: name
= "TestChaining"; if (exec
) TestChaining(); break;
1261 case 7: name
= "TestRootLabelSeparator"; if(exec
) TestRootLabelSeparator(); break;
1262 case 8: name
= "TestCompareReferenceImpl"; if(exec
) TestCompareReferenceImpl(); break;
1263 case 9: name
= "TestDataFile"; if(exec
) TestDataFile(); break;
1264 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1265 case 10: name
= "TestRefIDNA"; if(exec
) TestRefIDNA(); break;
1266 case 11: name
= "TestIDNAMonkeyTest"; if(exec
) TestIDNAMonkeyTest(); break;
1268 case 10: case 11: name
= "skip"; break;
1272 name
= "TestConformanceTestVectors";
1274 logln("TestSuite IDNA conf----"); logln();
1276 callTest(test
, par
);
1283 logln("TestSuite UTS46Test---"); logln();
1284 LocalPointer
<IntlTest
> test(createUTS46Test());
1285 callTest(*test
, par
);
1288 default: name
= ""; break; /*needed to end loop*/
1291 void TestIDNA::TestToASCII(){
1292 testToASCII("uidna_toASCII", uidna_toASCII
);
1294 void TestIDNA::TestToUnicode(){
1295 testToUnicode("uidna_toUnicode", uidna_toUnicode
);
1297 void TestIDNA::TestIDNToASCII(){
1298 testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII
);
1300 void TestIDNA::TestIDNToUnicode(){
1301 testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode
);
1303 void TestIDNA::TestCompare(){
1304 UErrorCode status
= U_ZERO_ERROR
;
1305 uidna_close(uidna_openUTS46(0, &status
)); // Fail quickly if no data.
1306 if (assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
1307 testCompare("uidna_compare",uidna_compare
);
1310 void TestIDNA::TestErrorCases(){
1311 testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII
,
1312 "uidna_IDNToUnicode",uidna_IDNToUnicode
);
1314 void TestIDNA::TestRootLabelSeparator(){
1315 UErrorCode status
= U_ZERO_ERROR
;
1316 uidna_close(uidna_openUTS46(0, &status
)); // Fail quickly if no data.
1317 if (assertSuccess("", status
, true, __FILE__
, __LINE__
)) {
1318 testRootLabelSeparator( "uidna_compare",uidna_compare
,
1319 "uidna_IDNToASCII", uidna_IDNToASCII
,
1320 "uidna_IDNToUnicode",uidna_IDNToUnicode
1324 void TestIDNA::TestChaining(){
1325 testChaining("uidna_toASCII",uidna_toASCII
, "uidna_toUnicode", uidna_toUnicode
);
1329 static const int loopCount
= 100;
1330 static const int maxCharCount
= 20;
1335 static UBool initialized
= FALSE
;
1338 srand((unsigned)time(NULL
));
1341 // Assume rand has at least 12 bits of precision
1343 for (uint32_t i
=0; i
<sizeof(l
); ++i
)
1344 ((char*)&l
)[i
] = (char)((rand() & 0x0FF0) >> 4);
1349 * Return a random integer i where 0 <= i < n.
1350 * A special function that gets random codepoints from planes 0,1,2 and 14
1352 static int32_t rand_uni()
1354 int32_t retVal
= (int32_t)(randul()& 0x3FFFF);
1355 if(retVal
>= 0x30000){
1361 static int32_t randi(int32_t n
){
1362 return (int32_t) (randul() % (n
+1));
1365 void getTestSource(UnicodeString
& fillIn
) {
1367 int32_t charCount
= (randi(maxCharCount
) + 1);
1368 while (i
<charCount
) {
1369 int32_t codepoint
= rand_uni();
1370 if(codepoint
== 0x0000){
1373 fillIn
.append((UChar32
)codepoint
);
1379 UnicodeString
TestIDNA::testCompareReferenceImpl(UnicodeString
& src
,
1380 TestFunc refIDNA
, const char* refIDNAName
,
1381 TestFunc uIDNA
, const char* uIDNAName
,
1384 const UChar
* srcUChars
= src
.getBuffer();
1385 UChar exp
[MAX_DEST_SIZE
]={0};
1386 int32_t expCap
= MAX_DEST_SIZE
, expLen
=0;
1387 UErrorCode expStatus
= U_ZERO_ERROR
;
1388 UParseError parseError
;
1390 logln("Comparing "+ UnicodeString(refIDNAName
)
1391 + " with "+ UnicodeString(uIDNAName
)
1392 +" for input: " + prettify(srcUChars
));
1394 expLen
= refIDNA(srcUChars
, src
.length()-1, exp
, expCap
,
1395 options
, &parseError
, &expStatus
);
1397 UChar got
[MAX_DEST_SIZE
]={0};
1398 int32_t gotCap
= MAX_DEST_SIZE
, gotLen
=0;
1399 UErrorCode gotStatus
= U_ZERO_ERROR
;
1401 gotLen
= uIDNA(srcUChars
, src
.length()-1, got
, gotCap
,
1402 options
, &parseError
, &gotStatus
);
1404 if(expStatus
!= gotStatus
){
1405 errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName
)
1406 + " with " + UnicodeString(uIDNAName
)
1407 + " Expected: " + UnicodeString(u_errorName(expStatus
))
1408 + " Got: " + UnicodeString(u_errorName(gotStatus
))
1409 + " for Source: "+ prettify(srcUChars
)
1410 + " Options: " + options
);
1411 return UnicodeString("");
1414 // now we know that both implementations yielded same error
1415 if(U_SUCCESS(expStatus
)){
1416 // compare the outputs if status == U_ZERO_ERROR
1417 if(u_strCompare(exp
, expLen
, got
, gotLen
, TRUE
) != 0){
1418 errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName
)
1419 + " with " + UnicodeString(uIDNAName
)
1420 + " Expected: " + prettify(UnicodeString(exp
, expLen
))
1421 + " Got: " + prettify(UnicodeString(got
, gotLen
))
1422 + " for Source: "+ prettify(srcUChars
)
1423 + " Options: " + options
);
1425 return UnicodeString(exp
, expLen
);
1428 logln("Got the same error while comparing "
1429 + UnicodeString(refIDNAName
)
1430 + " with "+ UnicodeString(uIDNAName
)
1431 +" for input: " + prettify(srcUChars
));
1433 return UnicodeString("");
1436 void TestIDNA::testCompareReferenceImpl(const UChar
* src
, int32_t srcLen
){
1437 UnicodeString
label(src
,srcLen
);
1438 label
.append((UChar
)0x0000);
1440 //test idnaref_toASCII and idnare
1441 UnicodeString asciiLabel
= testCompareReferenceImpl(label
,
1442 idnaref_toASCII
, "idnaref_toASCII",
1443 uidna_toASCII
, "uidna_toASCII",
1444 UIDNA_ALLOW_UNASSIGNED
);
1445 testCompareReferenceImpl(label
,
1446 idnaref_toASCII
, "idnaref_toASCII",
1447 uidna_toASCII
, "uidna_toASCII",
1449 testCompareReferenceImpl(label
,
1450 idnaref_toASCII
, "idnaref_toASCII",
1451 uidna_toASCII
, "uidna_toASCII",
1452 UIDNA_USE_STD3_RULES
);
1453 testCompareReferenceImpl(label
,
1454 idnaref_toASCII
, "idnaref_toASCII",
1455 uidna_toASCII
, "uidna_toASCII",
1456 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1458 if(asciiLabel
.length()!=0){
1459 asciiLabel
.append((UChar
)0x0000);
1462 testCompareReferenceImpl(asciiLabel
,
1463 idnaref_toUnicode
, "idnaref_toUnicode",
1464 uidna_toUnicode
, "uidna_toUnicode",
1465 UIDNA_ALLOW_UNASSIGNED
);
1466 testCompareReferenceImpl(asciiLabel
,
1467 idnaref_toUnicode
, "idnaref_toUnicode",
1468 uidna_toUnicode
, "uidna_toUnicode",
1470 testCompareReferenceImpl(asciiLabel
,
1471 idnaref_toUnicode
, "idnaref_toUnicode",
1472 uidna_toUnicode
, "uidna_toUnicode",
1473 UIDNA_USE_STD3_RULES
);
1474 testCompareReferenceImpl(asciiLabel
,
1475 idnaref_toUnicode
, "idnaref_toUnicode",
1476 uidna_toUnicode
, "uidna_toUnicode",
1477 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1481 const char* failures
[] ={
1482 "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1483 "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1486 void TestIDNA::TestIDNAMonkeyTest(){
1487 UnicodeString source
;
1488 UErrorCode status
= U_ZERO_ERROR
;
1491 getInstance(status
); // Init prep
1492 if (U_FAILURE(status
)) {
1493 dataerrln("Test could not initialize. Got %s", u_errorName(status
));
1497 for(i
=0; i
<loopCount
; i
++){
1499 getTestSource(source
);
1500 source
.append((UChar
)0x0000);
1501 const UChar
* src
= source
.getBuffer();
1502 testCompareReferenceImpl(src
,source
.length()-1);
1503 testCompareReferenceImpl(src
,source
.length()-1);
1507 for (i
=0; i
<UPRV_LENGTHOF(failures
); i
++){
1509 source
.append( UnicodeString(failures
[i
], -1, US_INV
) );
1510 source
= source
.unescape();
1511 source
.append((UChar
)0x0000);
1512 const UChar
*src
= source
.getBuffer();
1513 testCompareReferenceImpl(src
,source
.length()-1);
1514 //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1519 source
.append(UNICODE_STRING_SIMPLE("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C"));
1520 debug(source
.getBuffer(),source
.length(),UIDNA_ALLOW_UNASSIGNED
);
1522 { // test deletion of code points
1523 UnicodeString
source("\\u043f\\u00AD\\u034f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV
);
1524 source
= source
.unescape();
1525 UnicodeString
expected("\\u043f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV
);
1526 expected
= expected
.unescape();
1527 UnicodeString
ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1528 ascii
.append((UChar
)0x0000);
1529 testAPI(source
.getBuffer(),ascii
.getBuffer(), "uidna_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, uidna_toASCII
);
1531 testAPI(source
.getBuffer(),ascii
.getBuffer(), "idnaref_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, idnaref_toASCII
);
1533 testCompareReferenceImpl(source
.getBuffer(), source
.length()-1);
1538 void TestIDNA::TestCompareReferenceImpl(){
1540 UChar src
[2] = {0,0};
1544 UErrorCode dataStatus
= U_ZERO_ERROR
;
1545 loadTestData(dataStatus
);
1546 if(U_FAILURE(dataStatus
)) {
1547 dataerrln("Couldn't load test data: %s\n", u_errorName(dataStatus
)); // save us from thousands and thousands of errors
1550 uidna_close(uidna_openUTS46(0, &dataStatus
)); // Fail quickly if no data.
1551 if (!assertSuccess("", dataStatus
, true, __FILE__
, __LINE__
)) { return; }
1553 for (int32_t i
= 0; i
<= 0x10FFFF; i
++){
1554 if (quick
== TRUE
&& i
> 0x0FFF){
1558 // jump to E0000, no characters assigned in plain 3 to plain 13 as of Unicode 6.0
1562 src
[0] = U16_LEAD(i
);
1563 src
[1] = U16_TRAIL(i
);
1570 testCompareReferenceImpl(src
, srcLen
);
1574 void TestIDNA::TestRefIDNA(){
1575 UErrorCode status
= U_ZERO_ERROR
;
1577 getInstance(status
); // Init prep. Abort test early if no data.
1578 if (!assertSuccess("", status
, true, __FILE__
, __LINE__
)) { return; }
1580 testToASCII("idnaref_toASCII", idnaref_toASCII
);
1581 testToUnicode("idnaref_toUnicode", idnaref_toUnicode
);
1582 testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII
);
1583 testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode
);
1584 testCompare("idnaref_compare",idnaref_compare
);
1585 testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII
,
1586 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
);
1587 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1589 testRootLabelSeparator( "idnaref_compare",idnaref_compare
,
1590 "idnaref_IDNToASCII", idnaref_IDNToASCII
,
1591 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1593 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1597 void TestIDNA::TestDataFile(){
1600 TestIDNA::~TestIDNA(){
1607 NamePrepTransform
* TestIDNA::gPrep
= NULL
;
1609 NamePrepTransform
* TestIDNA::getInstance(UErrorCode
& status
){
1610 if(TestIDNA::gPrep
== NULL
){
1611 UParseError parseError
;
1612 TestIDNA::gPrep
= NamePrepTransform::createInstance(parseError
, status
);
1613 if(TestIDNA::gPrep
==NULL
){
1614 //status = U_MEMORY_ALLOCATION_ERROR;
1618 return TestIDNA::gPrep
;
1621 #endif /* #if !UCONFIG_NO_IDNA */