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"
35 #include "unicode/putil.h"
38 static const UChar unicodeIn
[][41] ={
40 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
41 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
44 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
48 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
49 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
50 0x0065, 0x0073, 0x006B, 0x0079, 0x0000
53 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
54 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
55 0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
58 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
59 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
60 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
61 0x0939, 0x0948, 0x0902, 0x0000
64 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
65 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
70 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
71 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
72 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
76 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
77 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
78 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
82 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
83 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
84 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
85 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
86 0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
89 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
93 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
94 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
95 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
96 0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
99 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
102 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
103 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
104 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
107 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
108 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
109 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
112 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
115 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
116 0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
119 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
123 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
125 // test non-BMP code points
127 0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
128 0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
132 0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
133 0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
139 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
143 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
148 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
149 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
150 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
151 0x0441, 0x0441, 0x043a, 0x0438
159 static const char *asciiIn
[] = {
160 "xn--egbpdaj6bu4bxfgehfvwxn",
161 "xn--ihqwcrb4cv8a8dqg056pqjye",
162 "xn--Proprostnemluvesky-uyb24dma41a",
163 "xn--4dbcagdahymbxekheh6e0a7fei0b",
164 "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
165 "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
166 /* "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
167 "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
168 "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
169 "xn--ihqwctvzc91f659drss3x8bo0yb",
170 "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
171 "xn--3B-ww4c5e180e575a65lsy2b",
172 "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
173 "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
174 "xn--2-u9tlzr9756bt3uc0v",
175 "xn--MajiKoi5-783gue6qz075azm5e",
176 "xn--de-jg4avhby1noc0d",
177 "xn--d9juau41awczczp",
179 "XN--db8CBHEJLGH4E0AL",
180 "xn--hxargifdar", // Greek
181 "xn--bonusaa-5bb1da", // Maltese
182 "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
186 static const char *domainNames
[] = {
187 "slip129-37-118-146.nc.us.ibm.net",
188 "saratoga.pe.utexas.edu",
189 "dial-120-45.ots.utexas.edu",
190 "woo-085.dorms.waller.net",
191 "hd30-049.hil.compuserve.com",
192 "pem203-31.pe.ttu.edu",
193 "56K-227.MaxTNT3.pdq.net",
194 "dial-36-2.ots.utexas.edu",
195 "slip129-37-23-152.ga.us.ibm.net",
196 "ts45ip119.cadvision.com",
197 "sdn-ts-004txaustP05.dialsprint.net",
198 "bar-tnt1s66.erols.com",
199 "101.st-louis-15.mo.dial-access.att.net",
201 "dial-13-2.ots.utexas.edu",
202 "net-redynet29.datamarkets.com.ar",
203 "ccs-shiva28.reacciun.net.ve",
204 "7.houston-11.tx.dial-access.att.net",
205 "ingw129-37-120-26.mo.us.ibm.net",
206 "dialup6.austintx.com",
208 "slip129-37-119-194.nc.us.ibm.net",
209 "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
210 "swprd1.innovplace.saskatoon.sk.ca",
211 "bikini.bologna.maraut.it",
212 "node91.subnet159-198-79.baxter.com",
213 "cust19.max5.new-york.ny.ms.uu.net",
214 "balexander.slip.andrew.cmu.edu",
215 "pool029.max2.denver.co.dynip.alter.net",
216 "cust49.max9.new-york.ny.ms.uu.net",
217 "s61.abq-dialin2.hollyberry.com",
218 "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
220 // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
221 "www.\\u00C2\\u00A4.com",
222 "www.\\u00C2\\u00A3.com",
223 // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
224 // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
230 // These yeild U_IDNA_PROHIBITED_ERROR
231 //"\\u00CF\\u0082.com",
232 //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
233 //"\\u00E2\\u0098\\u00BA.com",
234 "\\u00C3\\u00BC.com",
238 typedef struct ErrorCases ErrorCases
;
240 static const struct ErrorCases
{
245 UBool useSTD3ASCIIRules
;
252 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
253 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
254 0x070F,/*prohibited*/
255 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
256 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
259 "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
260 U_IDNA_PROHIBITED_ERROR
,
266 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
267 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
268 0x0221, 0x0234/*Unassigned code points*/,
269 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
272 "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
274 U_IDNA_UNASSIGNED_ERROR
,
279 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
280 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
281 0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
282 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
283 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
286 "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
287 U_IDNA_CHECK_BIDI_ERROR
,
292 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
293 /* labels cannot begin with an HYPHEN */
294 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
296 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
297 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
301 "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
302 U_IDNA_STD3_ASCII_RULES_ERROR
,
307 /* correct ACE-prefix followed by unicode */
308 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
309 0x0078, 0x006e, 0x002d,0x002d, /* ACE Prefix */
310 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
312 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
313 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
317 /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
318 "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
319 U_IDNA_ACE_PREFIX_ERROR
,
322 /* cannot verify U_IDNA_VERIFICATION_ERROR */
326 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
327 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
328 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
329 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
330 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
333 "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
334 U_IDNA_LABEL_TOO_LONG_ERROR
,
340 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
341 0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
342 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
345 "www.xn--01-tvdmo.com",
346 U_IDNA_CHECK_BIDI_ERROR
,
352 0x0077, 0x0077, 0x0077, 0x002e, // www.
353 0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
354 0x002e, 0x0063, 0x006f, 0x006d, // com.
357 "www.XN--ghbgi278xia.com",
358 U_IDNA_PROHIBITED_ERROR
,
363 0x0077, 0x0077, 0x0077, 0x002e, // www.
364 0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
365 0x002e, 0x0063, 0x006f, 0x006d, // com.
369 U_IDNA_STD3_ASCII_RULES_ERROR
,
374 0x0077, 0x0077, 0x0077, 0x002e, // www.
375 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
376 0x002e, 0x0063, 0x006f, 0x006d, // com.
380 U_IDNA_STD3_ASCII_RULES_ERROR
,
385 0x0077, 0x0077, 0x0077, 0x002e, // www.
386 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
387 0x002e, 0x0063, 0x006f, 0x006d, // com.
391 U_IDNA_STD3_ASCII_RULES_ERROR
,
396 0x0077, 0x0077, 0x0077, 0x002e, // www.
398 0x002e, 0x0063, 0x006f, 0x006d, // com.
402 U_IDNA_ZERO_LENGTH_LABEL_ERROR
,
408 U_ILLEGAL_ARGUMENT_ERROR
,
416 #define MAX_DEST_SIZE 300
418 void TestIDNA::debug(const UChar
* src
, int32_t srcLength
, int32_t options
){
419 UParseError parseError
;
420 UErrorCode transStatus
= U_ZERO_ERROR
;
421 UErrorCode prepStatus
= U_ZERO_ERROR
;
422 NamePrepTransform
* trans
= NamePrepTransform::createInstance(parseError
,transStatus
);
423 int32_t prepOptions
= (((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0);
424 LocalUStringPrepProfilePointer
prep(usprep_openByType(USPREP_RFC3491_NAMEPREP
,&prepStatus
));
425 UChar
*transOut
=NULL
, *prepOut
=NULL
;
426 int32_t transOutLength
=0, prepOutLength
=0;
429 transOutLength
= trans
->process(src
,srcLength
,transOut
, 0, prepOptions
>0, &parseError
, transStatus
);
430 if( transStatus
== U_BUFFER_OVERFLOW_ERROR
){
431 transStatus
= U_ZERO_ERROR
;
432 transOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* transOutLength
);
433 transOutLength
= trans
->process(src
,srcLength
,transOut
, transOutLength
, prepOptions
>0, &parseError
, transStatus
);
436 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, 0, prepOptions
, &parseError
, &prepStatus
);
438 if( prepStatus
== U_BUFFER_OVERFLOW_ERROR
){
439 prepStatus
= U_ZERO_ERROR
;
440 prepOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* prepOutLength
);
441 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, prepOutLength
, prepOptions
, &parseError
, &prepStatus
);
444 if(UnicodeString(transOut
,transOutLength
)!= UnicodeString(prepOut
, prepOutLength
)){
445 errln("Failed. Expected: " + prettify(UnicodeString(transOut
, transOutLength
))
446 + " Got: " + prettify(UnicodeString(prepOut
,prepOutLength
)));
453 void TestIDNA::testAPI(const UChar
* src
, const UChar
* expected
, const char* testName
,
454 UBool useSTD3ASCIIRules
,UErrorCode expectedStatus
,
455 UBool doCompare
, UBool testUnassigned
, TestFunc func
, UBool testSTD3ASCIIRules
){
457 UErrorCode status
= U_ZERO_ERROR
;
458 UChar destStack
[MAX_DEST_SIZE
];
461 int32_t expectedLen
= (expected
!= NULL
) ? u_strlen(expected
) : 0;
462 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
463 UParseError parseError
;
468 tSrcLen
= u_strlen(src
);
469 tSrc
=(UChar
*) malloc( U_SIZEOF_UCHAR
* tSrcLen
);
470 memcpy(tSrc
,src
,tSrcLen
* U_SIZEOF_UCHAR
);
473 // test null-terminated source and return value of number of UChars required
474 destLen
= func(src
,-1,NULL
,0,options
, &parseError
, &status
);
475 if(status
== U_BUFFER_OVERFLOW_ERROR
){
476 status
= U_ZERO_ERROR
; // reset error code
477 if(destLen
+1 < MAX_DEST_SIZE
){
479 destLen
= func(src
,-1,dest
,destLen
+1,options
, &parseError
, &status
);
480 // TODO : compare output with expected
481 if(U_SUCCESS(status
) && expectedStatus
!= U_IDNA_STD3_ASCII_RULES_ERROR
&& (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
482 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source. Expected : "
483 + prettify(UnicodeString(expected
,expectedLen
))
484 + " Got: " + prettify(UnicodeString(dest
,destLen
))
488 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
492 if(status
!= expectedStatus
){
493 errcheckln(status
, "Did not get the expected error for "+
494 UnicodeString(testName
)+
495 " null terminated source. Expected: " +UnicodeString(u_errorName(expectedStatus
))
496 + " Got: "+ UnicodeString(u_errorName(status
))
497 + " Source: " + prettify(UnicodeString(src
))
503 status
= U_ZERO_ERROR
;
504 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
505 if(status
== U_BUFFER_OVERFLOW_ERROR
){
506 status
= U_ZERO_ERROR
; // reset error code
507 if(destLen
+1 < MAX_DEST_SIZE
){
509 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
510 // TODO : compare output with expected
511 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
512 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
513 errln("Did not get the expected result for "+UnicodeString(testName
) +
514 " null terminated source "+ prettify(src
) +
515 " with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
))+
516 "Got: " + prettify(UnicodeString(dest
,destLen
)));
518 debug(src
,-1,options
| UIDNA_ALLOW_UNASSIGNED
);
522 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
525 //testing query string
526 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
527 errln( "Did not get the expected error for "+
528 UnicodeString(testName
)+
529 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
530 + " Got: "+ UnicodeString(u_errorName(status
))
531 + " Source: " + prettify(UnicodeString(src
))
536 status
= U_ZERO_ERROR
;
538 // test source with lengthand return value of number of UChars required
539 destLen
= func(tSrc
, tSrcLen
, NULL
,0,options
, &parseError
, &status
);
540 if(status
== U_BUFFER_OVERFLOW_ERROR
){
541 status
= U_ZERO_ERROR
; // reset error code
542 if(destLen
+1 < MAX_DEST_SIZE
){
544 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
, &parseError
, &status
);
545 // TODO : compare output with expected
546 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
547 errln("Did not get the expected result for %s with source length.\n",testName
);
550 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
554 if(status
!= expectedStatus
){
555 errln( "Did not get the expected error for "+
556 UnicodeString(testName
)+
557 " with source length. Expected: " +UnicodeString(u_errorName(expectedStatus
))
558 + " Got: "+ UnicodeString(u_errorName(status
))
559 + " Source: " + prettify(UnicodeString(src
))
563 status
= U_ZERO_ERROR
;
565 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
567 if(status
== U_BUFFER_OVERFLOW_ERROR
){
568 status
= U_ZERO_ERROR
; // reset error code
569 if(destLen
+1 < MAX_DEST_SIZE
){
571 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
572 // TODO : compare output with expected
573 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
574 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
577 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
580 //testing query string
581 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
582 errln( "Did not get the expected error for "+
583 UnicodeString(testName
)+
584 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
585 + " Got: "+ UnicodeString(u_errorName(status
))
586 + " Source: " + prettify(UnicodeString(src
))
591 status
= U_ZERO_ERROR
;
592 if(testSTD3ASCIIRules
==TRUE
){
593 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
594 if(status
== U_BUFFER_OVERFLOW_ERROR
){
595 status
= U_ZERO_ERROR
; // reset error code
596 if(destLen
+1 < MAX_DEST_SIZE
){
598 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
599 // TODO : compare output with expected
600 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
601 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
602 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
)));
606 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
609 //testing query string
610 if(status
!= expectedStatus
){
611 errln( "Did not get the expected error for "+
612 UnicodeString(testName
)+
613 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
614 + " Got: "+ UnicodeString(u_errorName(status
))
615 + " Source: " + prettify(UnicodeString(src
))
619 status
= U_ZERO_ERROR
;
621 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
623 if(status
== U_BUFFER_OVERFLOW_ERROR
){
624 status
= U_ZERO_ERROR
; // reset error code
625 if(destLen
+1 < MAX_DEST_SIZE
){
627 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
628 // TODO : compare output with expected
629 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
630 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
633 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
636 //testing query string
637 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
638 errln( "Did not get the expected error for "+
639 UnicodeString(testName
)+
640 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
641 + " Got: "+ UnicodeString(u_errorName(status
))
642 + " Source: " + prettify(UnicodeString(src
))
649 void TestIDNA::testCompare(const UChar
* s1
, int32_t s1Len
,
650 const UChar
* s2
, int32_t s2Len
,
651 const char* testName
, CompareFunc func
,
654 UErrorCode status
= U_ZERO_ERROR
;
655 int32_t retVal
= func(s1
,-1,s2
,-1,UIDNA_DEFAULT
,&status
);
657 if(isEqual
==TRUE
&& retVal
!=0){
658 errln("Did not get the expected result for %s with null termniated strings.\n",testName
);
660 if(U_FAILURE(status
)){
661 errcheckln(status
, "%s null terminated source failed. Error: %s", testName
,u_errorName(status
));
664 status
= U_ZERO_ERROR
;
665 retVal
= func(s1
,-1,s2
,-1,UIDNA_ALLOW_UNASSIGNED
,&status
);
667 if(isEqual
==TRUE
&& retVal
!=0){
668 errln("Did not get the expected result for %s with null termniated strings with options set.\n", testName
);
670 if(U_FAILURE(status
)){
671 errcheckln(status
, "%s null terminated source and options set failed. Error: %s",testName
, u_errorName(status
));
674 status
= U_ZERO_ERROR
;
675 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_DEFAULT
,&status
);
677 if(isEqual
==TRUE
&& retVal
!=0){
678 errln("Did not get the expected result for %s with string length.\n",testName
);
680 if(U_FAILURE(status
)){
681 errcheckln(status
, "%s with string length. Error: %s",testName
, u_errorName(status
));
684 status
= U_ZERO_ERROR
;
685 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_ALLOW_UNASSIGNED
,&status
);
687 if(isEqual
==TRUE
&& retVal
!=0){
688 errln("Did not get the expected result for %s with string length and options set.\n",testName
);
690 if(U_FAILURE(status
)){
691 errcheckln(status
, "%s with string length and options set. Error: %s", u_errorName(status
), testName
);
695 void TestIDNA::testToASCII(const char* testName
, TestFunc func
){
698 UChar buf
[MAX_DEST_SIZE
];
700 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
701 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
702 testAPI(unicodeIn
[i
], buf
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
707 void TestIDNA::testToUnicode(const char* testName
, TestFunc func
){
710 UChar buf
[MAX_DEST_SIZE
];
712 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
713 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
714 testAPI(buf
,unicodeIn
[i
],testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
719 void TestIDNA::testIDNToUnicode(const char* testName
, TestFunc func
){
721 UChar buf
[MAX_DEST_SIZE
];
722 UChar expected
[MAX_DEST_SIZE
];
723 UErrorCode status
= U_ZERO_ERROR
;
725 UParseError parseError
;
726 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
727 bufLen
= (int32_t)strlen(domainNames
[i
]);
728 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
729 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
730 if(U_FAILURE(status
)){
731 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
, i
, u_errorName(status
));
734 testAPI(buf
,expected
,testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
735 //test toUnicode with all labels in the string
736 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
737 if(U_FAILURE(status
)){
738 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
745 void TestIDNA::testIDNToASCII(const char* testName
, TestFunc func
){
747 UChar buf
[MAX_DEST_SIZE
];
748 UChar expected
[MAX_DEST_SIZE
];
749 UErrorCode status
= U_ZERO_ERROR
;
751 UParseError parseError
;
752 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
753 bufLen
= (int32_t)strlen(domainNames
[i
]);
754 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
755 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
756 if(U_FAILURE(status
)){
757 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
,i
, u_errorName(status
));
760 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
761 //test toASCII with all labels in the string
762 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, FALSE
, TRUE
, func
);
763 if(U_FAILURE(status
)){
764 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
771 void TestIDNA::testCompare(const char* testName
, CompareFunc func
){
775 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
776 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x0000};
777 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
779 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
781 uni0
.append(unicodeIn
[0]);
783 uni0
.append((UChar
)0x0000);
785 uni1
.append(unicodeIn
[1]);
787 uni1
.append((UChar
)0x0000);
789 ascii0
.append(asciiIn
[0]);
791 ascii0
.append((UChar
)0x0000);
793 ascii1
.append(asciiIn
[1]);
795 ascii1
.append((UChar
)0x0000);
797 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
799 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
802 // for every entry in unicodeIn array
803 // prepend www. and append .com
805 source
.append(unicodeIn
[i
]);
807 source
.append((UChar
)0x0000);
808 // a) compare it with itself
809 const UChar
* src
= source
.getBuffer();
810 int32_t srcLen
= u_strlen(src
); //subtract null
812 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
, TRUE
);
814 // b) compare it with asciiIn equivalent
815 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
817 // c) compare it with unicodeIn not equivalent
819 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
821 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
823 // d) compare it with asciiIn not equivalent
825 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
827 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
836 getNextSeperator(UChar
*src
,int32_t srcLength
,
842 *limit
= src
+ i
; // point to null
846 *limit
= src
+ (i
+1); // go past the delimiter
850 // we have not found the delimiter
852 *limit
= src
+srcLength
;
857 for(i
=0;i
<srcLength
;i
++){
859 *limit
= src
+ (i
+1); // go past the delimiter
863 // we have not found the delimiter
865 *limit
= src
+srcLength
;
871 void printPunycodeOutput(){
873 UChar dest
[MAX_DEST_SIZE
];
874 int32_t destCapacity
=MAX_DEST_SIZE
;
878 UBool caseFlags
[MAX_DEST_SIZE
];
880 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
881 ErrorCases errorCase
= errorCases
[i
];
882 UErrorCode status
= U_ZERO_ERROR
;
883 start
= errorCase
.unicode
;
884 int32_t srcLen
= u_strlen(start
);
885 labelLen
= getNextSeperator(start
,srcLen
,&limit
);
887 labelLen
=getNextSeperator(start
,srcLen
-labelLen
,&limit
);
888 int32_t destLen
= u_strToPunycode(dest
,destCapacity
,start
,labelLen
,caseFlags
, &status
);
889 if(U_FAILURE(status
)){
890 printf("u_strToPunycode failed for index %i\n",i
);
893 for(int32_t j
=0; j
<destLen
; j
++){
894 printf("%c",(char)dest
[j
]);
901 void TestIDNA::testErrorCases(const char* IDNToASCIIName
, TestFunc IDNToASCII
,
902 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
903 UChar buf
[MAX_DEST_SIZE
];
906 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
907 ErrorCases errorCase
= errorCases
[i
];
909 if(errorCase
.ascii
!= NULL
){
910 bufLen
= (int32_t)strlen(errorCase
.ascii
);
911 u_charsToUChars(errorCase
.ascii
,buf
, bufLen
+1);
914 memset(buf
,0,U_SIZEOF_UCHAR
*MAX_DEST_SIZE
);
917 if(errorCase
.unicode
[0]!=0){
918 src
= errorCase
.unicode
;
922 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
923 errorCase
.expected
, TRUE
, TRUE
, IDNToASCII
);
924 if(errorCase
.testLabel
==TRUE
){
926 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
927 errorCase
.expected
, FALSE
,TRUE
, IDNToASCII
);
929 if(errorCase
.testToUnicode
==TRUE
){
930 testAPI((src
==NULL
)? NULL
: buf
,src
,
931 IDNToUnicodeName
, errorCase
.useSTD3ASCIIRules
,
932 errorCase
.expected
, TRUE
, TRUE
, IDNToUnicode
);
939 void TestIDNA::testConformance(const char* toASCIIName, TestFunc toASCII,
940 const char* IDNToASCIIName, TestFunc IDNToASCII,
941 const char* IDNToUnicodeName, TestFunc IDNToUnicode,
942 const char* toUnicodeName, TestFunc toUnicode){
943 UChar src[MAX_DEST_SIZE];
945 UChar expected[MAX_DEST_SIZE];
946 int32_t expectedLen = 0;
947 for(int32_t i=0;i< UPRV_LENGTHOF(conformanceTestCases);i++){
948 const char* utf8Chars1 = conformanceTestCases[i].in;
949 int32_t utf8Chars1Len = (int32_t)strlen(utf8Chars1);
950 const char* utf8Chars2 = conformanceTestCases[i].out;
951 int32_t utf8Chars2Len = (utf8Chars2 == NULL) ? 0 : (int32_t)strlen(utf8Chars2);
953 UErrorCode status = U_ZERO_ERROR;
954 u_strFromUTF8(src,MAX_DEST_SIZE,&srcLen,utf8Chars1,utf8Chars1Len,&status);
955 if(U_FAILURE(status)){
956 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
959 if(utf8Chars2 != NULL){
960 u_strFromUTF8(expected,MAX_DEST_SIZE,&expectedLen,utf8Chars2,utf8Chars2Len, &status);
961 if(U_FAILURE(status)){
962 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
967 if(conformanceTestCases[i].expectedStatus != U_ZERO_ERROR){
969 testAPI(src,expected,
970 IDNToASCIIName, FALSE,
971 conformanceTestCases[i].expectedStatus,
973 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
976 testAPI(src,expected,
978 conformanceTestCases[i].expectedStatus, TRUE,
979 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
984 IDNToUnicodeName, FALSE,
985 conformanceTestCases[i].expectedStatus, TRUE, TRUE, IDNToUnicode);
987 toUnicodeName, FALSE,
988 conformanceTestCases[i].expectedStatus, TRUE, TRUE, toUnicode);
994 // test and ascertain
995 // func(func(func(src))) == func(src)
996 void TestIDNA::testChaining(const UChar
* src
,int32_t numIterations
,const char* testName
,
997 UBool useSTD3ASCIIRules
, UBool caseInsensitive
, TestFunc func
){
998 UChar even
[MAX_DEST_SIZE
];
999 UChar odd
[MAX_DEST_SIZE
];
1000 UChar expected
[MAX_DEST_SIZE
];
1001 int32_t i
=0,evenLen
=0,oddLen
=0,expectedLen
=0;
1002 UErrorCode status
= U_ZERO_ERROR
;
1003 int32_t srcLen
= u_strlen(src
);
1004 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
1005 UParseError parseError
;
1007 // test null-terminated source
1008 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
, options
, &parseError
, &status
);
1009 if(U_FAILURE(status
)){
1010 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1012 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1013 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1014 for(;i
<=numIterations
; i
++){
1016 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1017 if(U_FAILURE(status
)){
1018 errcheckln(status
, "%s null terminated source failed - %s",testName
, u_errorName(status
));
1022 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1023 if(U_FAILURE(status
)){
1024 errln("%s null terminated source failed\n",testName
);
1029 if(caseInsensitive
==TRUE
){
1030 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1031 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1033 errln("Chaining for %s null terminated source failed\n",testName
);
1036 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1037 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1039 errln("Chaining for %s null terminated source failed\n",testName
);
1043 // test null-terminated source
1044 status
= U_ZERO_ERROR
;
1045 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1046 if(U_FAILURE(status
)){
1047 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1049 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1050 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1051 for(;i
<=numIterations
; i
++){
1053 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1054 if(U_FAILURE(status
)){
1055 errcheckln(status
, "%s null terminated source with options set failed - %s",testName
, u_errorName(status
));
1059 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1060 if(U_FAILURE(status
)){
1061 errln("%s null terminated source with options set failed\n",testName
);
1066 if(caseInsensitive
==TRUE
){
1067 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1068 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1070 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1073 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1074 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1076 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1081 // test source with length
1082 status
= U_ZERO_ERROR
;
1083 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1084 if(U_FAILURE(status
)){
1085 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1087 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1088 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1089 for(;i
<=numIterations
; i
++){
1091 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1092 if(U_FAILURE(status
)){
1093 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1097 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1098 if(U_FAILURE(status
)){
1099 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1104 if(caseInsensitive
==TRUE
){
1105 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1106 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1108 errln("Chaining for %s source with source length failed\n",testName
);
1111 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1112 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1114 errln("Chaining for %s source with source length failed\n",testName
);
1117 status
= U_ZERO_ERROR
;
1118 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1119 if(U_FAILURE(status
)){
1120 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1122 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1123 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1124 for(;i
<=numIterations
; i
++){
1126 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1127 if(U_FAILURE(status
)){
1128 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1132 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1133 if(U_FAILURE(status
)){
1134 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1139 if(caseInsensitive
==TRUE
){
1140 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1141 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1143 errln("Chaining for %s source with source length and options set failed\n",testName
);
1146 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1147 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1149 errln("Chaining for %s source with source length and options set failed\n",testName
);
1153 void TestIDNA::testChaining(const char* toASCIIName
, TestFunc toASCII
,
1154 const char* toUnicodeName
, TestFunc toUnicode
){
1156 UChar buf
[MAX_DEST_SIZE
];
1158 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
1159 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
1160 testChaining(buf
,5,toUnicodeName
, FALSE
, FALSE
, toUnicode
);
1162 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1163 testChaining(unicodeIn
[i
], 5,toASCIIName
, FALSE
, TRUE
, toASCII
);
1168 void TestIDNA::testRootLabelSeparator(const char* testName
, CompareFunc func
,
1169 const char* IDNToASCIIName
, TestFunc IDNToASCII
,
1170 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
1174 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1175 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x002E, /* root label separator */0x0000};
1176 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1178 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
1180 uni0
.append(unicodeIn
[0]);
1182 uni0
.append((UChar
)0x0000);
1184 uni1
.append(unicodeIn
[1]);
1186 uni1
.append((UChar
)0x0000);
1188 ascii0
.append(asciiIn
[0]);
1190 ascii0
.append((UChar
)0x0000);
1192 ascii1
.append(asciiIn
[1]);
1194 ascii1
.append((UChar
)0x0000);
1196 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1198 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
1201 // for every entry in unicodeIn array
1202 // prepend www. and append .com
1204 source
.append(unicodeIn
[i
]);
1206 source
.append((UChar
)0x0000);
1208 const UChar
* src
= source
.getBuffer();
1209 int32_t srcLen
= u_strlen(src
); //subtract null
1211 // b) compare it with asciiIn equivalent
1212 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
1214 // a) compare it with itself
1215 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
,TRUE
);
1218 // IDNToASCII comparison
1219 testAPI(src
,buf
,IDNToASCIIName
,FALSE
,U_ZERO_ERROR
,TRUE
, TRUE
, IDNToASCII
);
1220 // IDNToUnicode comparison
1221 testAPI(buf
,src
,IDNToUnicodeName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, IDNToUnicode
);
1223 // c) compare it with unicodeIn not equivalent
1225 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
1227 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
1229 // d) compare it with asciiIn not equivalent
1231 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
1233 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
1238 //---------------------------------------------
1240 //---------------------------------------------
1242 extern IntlTest
*createUTS46Test();
1244 void TestIDNA::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* par
)
1246 if (exec
) logln((UnicodeString
)"TestSuite IDNA API ");
1249 case 0: name
= "TestToASCII"; if (exec
) TestToASCII(); break;
1250 case 1: name
= "TestToUnicode"; if (exec
) TestToUnicode(); break;
1251 case 2: name
= "TestIDNToASCII"; if (exec
) TestIDNToASCII(); break;
1252 case 3: name
= "TestIDNToUnicode"; if (exec
) TestIDNToUnicode(); break;
1253 case 4: name
= "TestCompare"; if (exec
) TestCompare(); break;
1254 case 5: name
= "TestErrorCases"; if (exec
) TestErrorCases(); break;
1255 case 6: name
= "TestChaining"; if (exec
) TestChaining(); break;
1256 case 7: name
= "TestRootLabelSeparator"; if(exec
) TestRootLabelSeparator(); break;
1257 case 8: name
= "TestCompareReferenceImpl"; if(exec
) TestCompareReferenceImpl(); break;
1258 case 9: name
= "TestDataFile"; if(exec
) TestDataFile(); break;
1259 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1260 case 10: name
= "TestRefIDNA"; if(exec
) TestRefIDNA(); break;
1261 case 11: name
= "TestIDNAMonkeyTest"; if(exec
) TestIDNAMonkeyTest(); break;
1263 case 10: case 11: name
= "skip"; break;
1267 name
= "TestConformanceTestVectors";
1269 logln("TestSuite IDNA conf----"); logln();
1271 callTest(test
, par
);
1278 logln("TestSuite UTS46Test---"); logln();
1279 LocalPointer
<IntlTest
> test(createUTS46Test());
1280 callTest(*test
, par
);
1283 default: name
= ""; break; /*needed to end loop*/
1286 void TestIDNA::TestToASCII(){
1287 testToASCII("uidna_toASCII", uidna_toASCII
);
1289 void TestIDNA::TestToUnicode(){
1290 testToUnicode("uidna_toUnicode", uidna_toUnicode
);
1292 void TestIDNA::TestIDNToASCII(){
1293 testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII
);
1295 void TestIDNA::TestIDNToUnicode(){
1296 testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode
);
1298 void TestIDNA::TestCompare(){
1299 testCompare("uidna_compare",uidna_compare
);
1301 void TestIDNA::TestErrorCases(){
1302 testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII
,
1303 "uidna_IDNToUnicode",uidna_IDNToUnicode
);
1305 void TestIDNA::TestRootLabelSeparator(){
1306 testRootLabelSeparator( "uidna_compare",uidna_compare
,
1307 "uidna_IDNToASCII", uidna_IDNToASCII
,
1308 "uidna_IDNToUnicode",uidna_IDNToUnicode
1311 void TestIDNA::TestChaining(){
1312 testChaining("uidna_toASCII",uidna_toASCII
, "uidna_toUnicode", uidna_toUnicode
);
1316 static const int loopCount
= 100;
1317 static const int maxCharCount
= 20;
1322 static UBool initialized
= FALSE
;
1325 srand((unsigned)time(NULL
));
1328 // Assume rand has at least 12 bits of precision
1330 for (uint32_t i
=0; i
<sizeof(l
); ++i
)
1331 ((char*)&l
)[i
] = (char)((rand() & 0x0FF0) >> 4);
1336 * Return a random integer i where 0 <= i < n.
1337 * A special function that gets random codepoints from planes 0,1,2 and 14
1339 static int32_t rand_uni()
1341 int32_t retVal
= (int32_t)(randul()& 0x3FFFF);
1342 if(retVal
>= 0x30000){
1348 static int32_t randi(int32_t n
){
1349 return (int32_t) (randul() % (n
+1));
1352 void getTestSource(UnicodeString
& fillIn
) {
1354 int32_t charCount
= (randi(maxCharCount
) + 1);
1355 while (i
<charCount
) {
1356 int32_t codepoint
= rand_uni();
1357 if(codepoint
== 0x0000){
1360 fillIn
.append((UChar32
)codepoint
);
1366 UnicodeString
TestIDNA::testCompareReferenceImpl(UnicodeString
& src
,
1367 TestFunc refIDNA
, const char* refIDNAName
,
1368 TestFunc uIDNA
, const char* uIDNAName
,
1371 const UChar
* srcUChars
= src
.getBuffer();
1372 UChar exp
[MAX_DEST_SIZE
]={0};
1373 int32_t expCap
= MAX_DEST_SIZE
, expLen
=0;
1374 UErrorCode expStatus
= U_ZERO_ERROR
;
1375 UParseError parseError
;
1377 logln("Comparing "+ UnicodeString(refIDNAName
)
1378 + " with "+ UnicodeString(uIDNAName
)
1379 +" for input: " + prettify(srcUChars
));
1381 expLen
= refIDNA(srcUChars
, src
.length()-1, exp
, expCap
,
1382 options
, &parseError
, &expStatus
);
1384 UChar got
[MAX_DEST_SIZE
]={0};
1385 int32_t gotCap
= MAX_DEST_SIZE
, gotLen
=0;
1386 UErrorCode gotStatus
= U_ZERO_ERROR
;
1388 gotLen
= uIDNA(srcUChars
, src
.length()-1, got
, gotCap
,
1389 options
, &parseError
, &gotStatus
);
1391 if(expStatus
!= gotStatus
){
1392 errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName
)
1393 + " with " + UnicodeString(uIDNAName
)
1394 + " Expected: " + UnicodeString(u_errorName(expStatus
))
1395 + " Got: " + UnicodeString(u_errorName(gotStatus
))
1396 + " for Source: "+ prettify(srcUChars
)
1397 + " Options: " + options
);
1398 return UnicodeString("");
1401 // now we know that both implementations yielded same error
1402 if(U_SUCCESS(expStatus
)){
1403 // compare the outputs if status == U_ZERO_ERROR
1404 if(u_strCompare(exp
, expLen
, got
, gotLen
, TRUE
) != 0){
1405 errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName
)
1406 + " with " + UnicodeString(uIDNAName
)
1407 + " Expected: " + prettify(UnicodeString(exp
, expLen
))
1408 + " Got: " + prettify(UnicodeString(got
, gotLen
))
1409 + " for Source: "+ prettify(srcUChars
)
1410 + " Options: " + options
);
1412 return UnicodeString(exp
, expLen
);
1415 logln("Got the same error while comparing "
1416 + UnicodeString(refIDNAName
)
1417 + " with "+ UnicodeString(uIDNAName
)
1418 +" for input: " + prettify(srcUChars
));
1420 return UnicodeString("");
1423 void TestIDNA::testCompareReferenceImpl(const UChar
* src
, int32_t srcLen
){
1424 UnicodeString
label(src
,srcLen
);
1425 label
.append((UChar
)0x0000);
1427 //test idnaref_toASCII and idnare
1428 UnicodeString asciiLabel
= testCompareReferenceImpl(label
,
1429 idnaref_toASCII
, "idnaref_toASCII",
1430 uidna_toASCII
, "uidna_toASCII",
1431 UIDNA_ALLOW_UNASSIGNED
);
1432 testCompareReferenceImpl(label
,
1433 idnaref_toASCII
, "idnaref_toASCII",
1434 uidna_toASCII
, "uidna_toASCII",
1436 testCompareReferenceImpl(label
,
1437 idnaref_toASCII
, "idnaref_toASCII",
1438 uidna_toASCII
, "uidna_toASCII",
1439 UIDNA_USE_STD3_RULES
);
1440 testCompareReferenceImpl(label
,
1441 idnaref_toASCII
, "idnaref_toASCII",
1442 uidna_toASCII
, "uidna_toASCII",
1443 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1445 if(asciiLabel
.length()!=0){
1446 asciiLabel
.append((UChar
)0x0000);
1449 testCompareReferenceImpl(asciiLabel
,
1450 idnaref_toUnicode
, "idnaref_toUnicode",
1451 uidna_toUnicode
, "uidna_toUnicode",
1452 UIDNA_ALLOW_UNASSIGNED
);
1453 testCompareReferenceImpl(asciiLabel
,
1454 idnaref_toUnicode
, "idnaref_toUnicode",
1455 uidna_toUnicode
, "uidna_toUnicode",
1457 testCompareReferenceImpl(asciiLabel
,
1458 idnaref_toUnicode
, "idnaref_toUnicode",
1459 uidna_toUnicode
, "uidna_toUnicode",
1460 UIDNA_USE_STD3_RULES
);
1461 testCompareReferenceImpl(asciiLabel
,
1462 idnaref_toUnicode
, "idnaref_toUnicode",
1463 uidna_toUnicode
, "uidna_toUnicode",
1464 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1468 const char* failures
[] ={
1469 "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1470 "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1473 void TestIDNA::TestIDNAMonkeyTest(){
1474 UnicodeString source
;
1475 UErrorCode status
= U_ZERO_ERROR
;
1478 getInstance(status
); // Init prep
1479 if (U_FAILURE(status
)) {
1480 dataerrln("Test could not initialize. Got %s", u_errorName(status
));
1484 for(i
=0; i
<loopCount
; i
++){
1486 getTestSource(source
);
1487 source
.append((UChar
)0x0000);
1488 const UChar
* src
= source
.getBuffer();
1489 testCompareReferenceImpl(src
,source
.length()-1);
1490 testCompareReferenceImpl(src
,source
.length()-1);
1494 for (i
=0; i
<UPRV_LENGTHOF(failures
); i
++){
1496 source
.append( UnicodeString(failures
[i
], -1, US_INV
) );
1497 source
= source
.unescape();
1498 source
.append((UChar
)0x0000);
1499 const UChar
*src
= source
.getBuffer();
1500 testCompareReferenceImpl(src
,source
.length()-1);
1501 //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1506 source
.append(UNICODE_STRING_SIMPLE("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C"));
1507 debug(source
.getBuffer(),source
.length(),UIDNA_ALLOW_UNASSIGNED
);
1509 { // test deletion of code points
1510 UnicodeString
source("\\u043f\\u00AD\\u034f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV
);
1511 source
= source
.unescape();
1512 UnicodeString
expected("\\u043f\\u043e\\u0447\\u0435\\u043c\\u0443\\u0436\\u0435\\u043e\\u043d\\u0438\\u043d\\u0435\\u0433\\u043e\\u0432\\u043e\\u0440\\u044f\\u0442\\u043f\\u043e\\u0440\\u0443\\u0441\\u0441\\u043a\\u0438\\u0000", -1, US_INV
);
1513 expected
= expected
.unescape();
1514 UnicodeString
ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1515 ascii
.append((UChar
)0x0000);
1516 testAPI(source
.getBuffer(),ascii
.getBuffer(), "uidna_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, uidna_toASCII
);
1518 testAPI(source
.getBuffer(),ascii
.getBuffer(), "idnaref_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, idnaref_toASCII
);
1520 testCompareReferenceImpl(source
.getBuffer(), source
.length()-1);
1525 void TestIDNA::TestCompareReferenceImpl(){
1527 UChar src
[2] = {0,0};
1532 UErrorCode dataStatus
= U_ZERO_ERROR
;
1533 loadTestData(dataStatus
);
1534 if(U_FAILURE(dataStatus
)) {
1535 dataerrln("Couldn't load test data: %s\n", u_errorName(dataStatus
)); // save us from thousands and thousands of errors
1540 for (int32_t i
= 0; i
<= 0x10FFFF; i
++){
1541 if (quick
== TRUE
&& i
> 0x0FFF){
1545 // jump to E0000, no characters assigned in plain 3 to plain 13 as of Unicode 6.0
1549 src
[0] = U16_LEAD(i
);
1550 src
[1] = U16_TRAIL(i
);
1557 testCompareReferenceImpl(src
, srcLen
);
1561 void TestIDNA::TestRefIDNA(){
1562 UErrorCode status
= U_ZERO_ERROR
;
1563 getInstance(status
); // Init prep
1564 if (U_FAILURE(status
)) {
1565 if (status
== U_FILE_ACCESS_ERROR
) {
1566 dataerrln("Test could not initialize. Got %s", u_errorName(status
));
1571 testToASCII("idnaref_toASCII", idnaref_toASCII
);
1572 testToUnicode("idnaref_toUnicode", idnaref_toUnicode
);
1573 testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII
);
1574 testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode
);
1575 testCompare("idnaref_compare",idnaref_compare
);
1576 testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII
,
1577 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
);
1578 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1580 testRootLabelSeparator( "idnaref_compare",idnaref_compare
,
1581 "idnaref_IDNToASCII", idnaref_IDNToASCII
,
1582 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1584 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1588 void TestIDNA::TestDataFile(){
1591 TestIDNA::~TestIDNA(){
1598 NamePrepTransform
* TestIDNA::gPrep
= NULL
;
1600 NamePrepTransform
* TestIDNA::getInstance(UErrorCode
& status
){
1601 if(TestIDNA::gPrep
== NULL
){
1602 UParseError parseError
;
1603 TestIDNA::gPrep
= NamePrepTransform::createInstance(parseError
, status
);
1604 if(TestIDNA::gPrep
==NULL
){
1605 //status = U_MEMORY_ALLOCATION_ERROR;
1609 return TestIDNA::gPrep
;
1612 #endif /* #if !UCONFIG_NO_IDNA */