2 *******************************************************************************
4 * Copyright (C) 2003-2016, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * file name: testidna.cpp
10 * tab size: 8 (not used)
13 * created on: 2003feb1
14 * created by: Ram Viswanadha
17 #include "unicode/utypes.h"
19 #if !UCONFIG_NO_IDNA && !UCONFIG_NO_TRANSLITERATION
25 #include "unicode/localpointer.h"
26 #include "unicode/ustring.h"
27 #include "unicode/usprep.h"
28 #include "unicode/uniset.h"
33 #include "unicode/putil.h"
36 static const UChar unicodeIn
[][41] ={
38 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
39 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
42 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
46 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
47 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
48 0x0065, 0x0073, 0x006B, 0x0079, 0x0000
51 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
52 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
53 0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
56 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
57 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
58 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
59 0x0939, 0x0948, 0x0902, 0x0000
62 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
63 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
68 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
69 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
70 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
74 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
75 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
76 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
80 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
81 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
82 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
83 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
84 0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
87 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
91 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
92 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
93 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
94 0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
97 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
100 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
101 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
102 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
105 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
106 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
107 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
110 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
113 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
114 0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
117 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
121 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
123 // test non-BMP code points
125 0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
126 0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
130 0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
131 0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
137 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
141 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
146 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
147 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
148 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
149 0x0441, 0x0441, 0x043a, 0x0438
157 static const char *asciiIn
[] = {
158 "xn--egbpdaj6bu4bxfgehfvwxn",
159 "xn--ihqwcrb4cv8a8dqg056pqjye",
160 "xn--Proprostnemluvesky-uyb24dma41a",
161 "xn--4dbcagdahymbxekheh6e0a7fei0b",
162 "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
163 "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
164 /* "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
165 "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
166 "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
167 "xn--ihqwctvzc91f659drss3x8bo0yb",
168 "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
169 "xn--3B-ww4c5e180e575a65lsy2b",
170 "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
171 "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
172 "xn--2-u9tlzr9756bt3uc0v",
173 "xn--MajiKoi5-783gue6qz075azm5e",
174 "xn--de-jg4avhby1noc0d",
175 "xn--d9juau41awczczp",
177 "XN--db8CBHEJLGH4E0AL",
178 "xn--hxargifdar", // Greek
179 "xn--bonusaa-5bb1da", // Maltese
180 "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
184 static const char *domainNames
[] = {
185 "slip129-37-118-146.nc.us.ibm.net",
186 "saratoga.pe.utexas.edu",
187 "dial-120-45.ots.utexas.edu",
188 "woo-085.dorms.waller.net",
189 "hd30-049.hil.compuserve.com",
190 "pem203-31.pe.ttu.edu",
191 "56K-227.MaxTNT3.pdq.net",
192 "dial-36-2.ots.utexas.edu",
193 "slip129-37-23-152.ga.us.ibm.net",
194 "ts45ip119.cadvision.com",
195 "sdn-ts-004txaustP05.dialsprint.net",
196 "bar-tnt1s66.erols.com",
197 "101.st-louis-15.mo.dial-access.att.net",
199 "dial-13-2.ots.utexas.edu",
200 "net-redynet29.datamarkets.com.ar",
201 "ccs-shiva28.reacciun.net.ve",
202 "7.houston-11.tx.dial-access.att.net",
203 "ingw129-37-120-26.mo.us.ibm.net",
204 "dialup6.austintx.com",
206 "slip129-37-119-194.nc.us.ibm.net",
207 "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
208 "swprd1.innovplace.saskatoon.sk.ca",
209 "bikini.bologna.maraut.it",
210 "node91.subnet159-198-79.baxter.com",
211 "cust19.max5.new-york.ny.ms.uu.net",
212 "balexander.slip.andrew.cmu.edu",
213 "pool029.max2.denver.co.dynip.alter.net",
214 "cust49.max9.new-york.ny.ms.uu.net",
215 "s61.abq-dialin2.hollyberry.com",
216 "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
218 // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
219 "www.\\u00C2\\u00A4.com",
220 "www.\\u00C2\\u00A3.com",
221 // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
222 // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
228 // These yeild U_IDNA_PROHIBITED_ERROR
229 //"\\u00CF\\u0082.com",
230 //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
231 //"\\u00E2\\u0098\\u00BA.com",
232 "\\u00C3\\u00BC.com",
236 typedef struct ErrorCases ErrorCases
;
238 static const struct ErrorCases
{
243 UBool useSTD3ASCIIRules
;
250 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
251 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
252 0x070F,/*prohibited*/
253 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
254 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
257 "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
258 U_IDNA_PROHIBITED_ERROR
,
264 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
265 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
266 0x0221, 0x0234/*Unassigned code points*/,
267 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
270 "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
272 U_IDNA_UNASSIGNED_ERROR
,
277 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
278 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
279 0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
280 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
281 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
284 "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
285 U_IDNA_CHECK_BIDI_ERROR
,
290 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
291 /* labels cannot begin with an HYPHEN */
292 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
294 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
295 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
299 "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
300 U_IDNA_STD3_ASCII_RULES_ERROR
,
305 /* correct ACE-prefix followed by unicode */
306 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
307 0x0078, 0x006e, 0x002d,0x002d, /* ACE Prefix */
308 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
310 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
311 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
315 /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
316 "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
317 U_IDNA_ACE_PREFIX_ERROR
,
320 /* cannot verify U_IDNA_VERIFICATION_ERROR */
324 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
325 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
326 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
327 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
328 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
331 "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
332 U_IDNA_LABEL_TOO_LONG_ERROR
,
338 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
339 0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
340 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
343 "www.xn--01-tvdmo.com",
344 U_IDNA_CHECK_BIDI_ERROR
,
350 0x0077, 0x0077, 0x0077, 0x002e, // www.
351 0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
352 0x002e, 0x0063, 0x006f, 0x006d, // com.
355 "www.XN--ghbgi278xia.com",
356 U_IDNA_PROHIBITED_ERROR
,
361 0x0077, 0x0077, 0x0077, 0x002e, // www.
362 0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
363 0x002e, 0x0063, 0x006f, 0x006d, // com.
367 U_IDNA_STD3_ASCII_RULES_ERROR
,
372 0x0077, 0x0077, 0x0077, 0x002e, // www.
373 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
374 0x002e, 0x0063, 0x006f, 0x006d, // com.
378 U_IDNA_STD3_ASCII_RULES_ERROR
,
383 0x0077, 0x0077, 0x0077, 0x002e, // www.
384 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
385 0x002e, 0x0063, 0x006f, 0x006d, // com.
389 U_IDNA_STD3_ASCII_RULES_ERROR
,
394 0x0077, 0x0077, 0x0077, 0x002e, // www.
396 0x002e, 0x0063, 0x006f, 0x006d, // com.
400 U_IDNA_ZERO_LENGTH_LABEL_ERROR
,
406 U_ILLEGAL_ARGUMENT_ERROR
,
414 #define MAX_DEST_SIZE 300
416 void TestIDNA::debug(const UChar
* src
, int32_t srcLength
, int32_t options
){
417 UParseError parseError
;
418 UErrorCode transStatus
= U_ZERO_ERROR
;
419 UErrorCode prepStatus
= U_ZERO_ERROR
;
420 NamePrepTransform
* trans
= NamePrepTransform::createInstance(parseError
,transStatus
);
421 int32_t prepOptions
= (((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0);
422 LocalUStringPrepProfilePointer
prep(usprep_openByType(USPREP_RFC3491_NAMEPREP
,&prepStatus
));
423 UChar
*transOut
=NULL
, *prepOut
=NULL
;
424 int32_t transOutLength
=0, prepOutLength
=0;
427 transOutLength
= trans
->process(src
,srcLength
,transOut
, 0, prepOptions
>0, &parseError
, transStatus
);
428 if( transStatus
== U_BUFFER_OVERFLOW_ERROR
){
429 transStatus
= U_ZERO_ERROR
;
430 transOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* transOutLength
);
431 transOutLength
= trans
->process(src
,srcLength
,transOut
, transOutLength
, prepOptions
>0, &parseError
, transStatus
);
434 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, 0, prepOptions
, &parseError
, &prepStatus
);
436 if( prepStatus
== U_BUFFER_OVERFLOW_ERROR
){
437 prepStatus
= U_ZERO_ERROR
;
438 prepOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* prepOutLength
);
439 prepOutLength
= usprep_prepare(prep
.getAlias(), src
, srcLength
, prepOut
, prepOutLength
, prepOptions
, &parseError
, &prepStatus
);
442 if(UnicodeString(transOut
,transOutLength
)!= UnicodeString(prepOut
, prepOutLength
)){
443 errln("Failed. Expected: " + prettify(UnicodeString(transOut
, transOutLength
))
444 + " Got: " + prettify(UnicodeString(prepOut
,prepOutLength
)));
451 void TestIDNA::testAPI(const UChar
* src
, const UChar
* expected
, const char* testName
,
452 UBool useSTD3ASCIIRules
,UErrorCode expectedStatus
,
453 UBool doCompare
, UBool testUnassigned
, TestFunc func
, UBool testSTD3ASCIIRules
){
455 UErrorCode status
= U_ZERO_ERROR
;
456 UChar destStack
[MAX_DEST_SIZE
];
459 int32_t expectedLen
= (expected
!= NULL
) ? u_strlen(expected
) : 0;
460 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
461 UParseError parseError
;
466 tSrcLen
= u_strlen(src
);
467 tSrc
=(UChar
*) malloc( U_SIZEOF_UCHAR
* tSrcLen
);
468 memcpy(tSrc
,src
,tSrcLen
* U_SIZEOF_UCHAR
);
471 // test null-terminated source and return value of number of UChars required
472 destLen
= func(src
,-1,NULL
,0,options
, &parseError
, &status
);
473 if(status
== U_BUFFER_OVERFLOW_ERROR
){
474 status
= U_ZERO_ERROR
; // reset error code
475 if(destLen
+1 < MAX_DEST_SIZE
){
477 destLen
= func(src
,-1,dest
,destLen
+1,options
, &parseError
, &status
);
478 // TODO : compare output with expected
479 if(U_SUCCESS(status
) && expectedStatus
!= U_IDNA_STD3_ASCII_RULES_ERROR
&& (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
480 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source. Expected : "
481 + prettify(UnicodeString(expected
,expectedLen
))
482 + " Got: " + prettify(UnicodeString(dest
,destLen
))
486 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
490 if(status
!= expectedStatus
){
491 errcheckln(status
, "Did not get the expected error for "+
492 UnicodeString(testName
)+
493 " null terminated source. Expected: " +UnicodeString(u_errorName(expectedStatus
))
494 + " Got: "+ UnicodeString(u_errorName(status
))
495 + " Source: " + prettify(UnicodeString(src
))
501 status
= U_ZERO_ERROR
;
502 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
503 if(status
== U_BUFFER_OVERFLOW_ERROR
){
504 status
= U_ZERO_ERROR
; // reset error code
505 if(destLen
+1 < MAX_DEST_SIZE
){
507 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
508 // TODO : compare output with expected
509 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
510 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
511 errln("Did not get the expected result for "+UnicodeString(testName
) +
512 " null terminated source "+ prettify(src
) +
513 " with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
))+
514 "Got: " + prettify(UnicodeString(dest
,destLen
)));
516 debug(src
,-1,options
| UIDNA_ALLOW_UNASSIGNED
);
520 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
523 //testing query string
524 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
525 errln( "Did not get the expected error for "+
526 UnicodeString(testName
)+
527 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
528 + " Got: "+ UnicodeString(u_errorName(status
))
529 + " Source: " + prettify(UnicodeString(src
))
534 status
= U_ZERO_ERROR
;
536 // test source with lengthand return value of number of UChars required
537 destLen
= func(tSrc
, tSrcLen
, NULL
,0,options
, &parseError
, &status
);
538 if(status
== U_BUFFER_OVERFLOW_ERROR
){
539 status
= U_ZERO_ERROR
; // reset error code
540 if(destLen
+1 < MAX_DEST_SIZE
){
542 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
, &parseError
, &status
);
543 // TODO : compare output with expected
544 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
545 errln("Did not get the expected result for %s with source length.\n",testName
);
548 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
552 if(status
!= expectedStatus
){
553 errln( "Did not get the expected error for "+
554 UnicodeString(testName
)+
555 " with source length. Expected: " +UnicodeString(u_errorName(expectedStatus
))
556 + " Got: "+ UnicodeString(u_errorName(status
))
557 + " Source: " + prettify(UnicodeString(src
))
561 status
= U_ZERO_ERROR
;
563 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
565 if(status
== U_BUFFER_OVERFLOW_ERROR
){
566 status
= U_ZERO_ERROR
; // reset error code
567 if(destLen
+1 < MAX_DEST_SIZE
){
569 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
570 // TODO : compare output with expected
571 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
572 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
575 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
578 //testing query string
579 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
580 errln( "Did not get the expected error for "+
581 UnicodeString(testName
)+
582 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
583 + " Got: "+ UnicodeString(u_errorName(status
))
584 + " Source: " + prettify(UnicodeString(src
))
589 status
= U_ZERO_ERROR
;
590 if(testSTD3ASCIIRules
==TRUE
){
591 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
592 if(status
== U_BUFFER_OVERFLOW_ERROR
){
593 status
= U_ZERO_ERROR
; // reset error code
594 if(destLen
+1 < MAX_DEST_SIZE
){
596 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
597 // TODO : compare output with expected
598 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
599 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
600 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
)));
604 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
607 //testing query string
608 if(status
!= expectedStatus
){
609 errln( "Did not get the expected error for "+
610 UnicodeString(testName
)+
611 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
612 + " Got: "+ UnicodeString(u_errorName(status
))
613 + " Source: " + prettify(UnicodeString(src
))
617 status
= U_ZERO_ERROR
;
619 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
621 if(status
== U_BUFFER_OVERFLOW_ERROR
){
622 status
= U_ZERO_ERROR
; // reset error code
623 if(destLen
+1 < MAX_DEST_SIZE
){
625 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
626 // TODO : compare output with expected
627 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
628 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
631 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
634 //testing query string
635 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
636 errln( "Did not get the expected error for "+
637 UnicodeString(testName
)+
638 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
639 + " Got: "+ UnicodeString(u_errorName(status
))
640 + " Source: " + prettify(UnicodeString(src
))
647 void TestIDNA::testCompare(const UChar
* s1
, int32_t s1Len
,
648 const UChar
* s2
, int32_t s2Len
,
649 const char* testName
, CompareFunc func
,
652 UErrorCode status
= U_ZERO_ERROR
;
653 int32_t retVal
= func(s1
,-1,s2
,-1,UIDNA_DEFAULT
,&status
);
655 if(isEqual
==TRUE
&& retVal
!=0){
656 errln("Did not get the expected result for %s with null termniated strings.\n",testName
);
658 if(U_FAILURE(status
)){
659 errcheckln(status
, "%s null terminated source failed. Error: %s", testName
,u_errorName(status
));
662 status
= U_ZERO_ERROR
;
663 retVal
= func(s1
,-1,s2
,-1,UIDNA_ALLOW_UNASSIGNED
,&status
);
665 if(isEqual
==TRUE
&& retVal
!=0){
666 errln("Did not get the expected result for %s with null termniated strings with options set.\n", testName
);
668 if(U_FAILURE(status
)){
669 errcheckln(status
, "%s null terminated source and options set failed. Error: %s",testName
, u_errorName(status
));
672 status
= U_ZERO_ERROR
;
673 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_DEFAULT
,&status
);
675 if(isEqual
==TRUE
&& retVal
!=0){
676 errln("Did not get the expected result for %s with string length.\n",testName
);
678 if(U_FAILURE(status
)){
679 errcheckln(status
, "%s with string length. Error: %s",testName
, u_errorName(status
));
682 status
= U_ZERO_ERROR
;
683 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_ALLOW_UNASSIGNED
,&status
);
685 if(isEqual
==TRUE
&& retVal
!=0){
686 errln("Did not get the expected result for %s with string length and options set.\n",testName
);
688 if(U_FAILURE(status
)){
689 errcheckln(status
, "%s with string length and options set. Error: %s", u_errorName(status
), testName
);
693 void TestIDNA::testToASCII(const char* testName
, TestFunc func
){
696 UChar buf
[MAX_DEST_SIZE
];
698 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
699 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
700 testAPI(unicodeIn
[i
], buf
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
705 void TestIDNA::testToUnicode(const char* testName
, TestFunc func
){
708 UChar buf
[MAX_DEST_SIZE
];
710 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
711 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
712 testAPI(buf
,unicodeIn
[i
],testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
717 void TestIDNA::testIDNToUnicode(const char* testName
, TestFunc func
){
719 UChar buf
[MAX_DEST_SIZE
];
720 UChar expected
[MAX_DEST_SIZE
];
721 UErrorCode status
= U_ZERO_ERROR
;
723 UParseError parseError
;
724 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
725 bufLen
= (int32_t)strlen(domainNames
[i
]);
726 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
727 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
728 if(U_FAILURE(status
)){
729 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
, i
, u_errorName(status
));
732 testAPI(buf
,expected
,testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
733 //test toUnicode with all labels in the string
734 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
735 if(U_FAILURE(status
)){
736 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
743 void TestIDNA::testIDNToASCII(const char* testName
, TestFunc func
){
745 UChar buf
[MAX_DEST_SIZE
];
746 UChar expected
[MAX_DEST_SIZE
];
747 UErrorCode status
= U_ZERO_ERROR
;
749 UParseError parseError
;
750 for(i
=0;i
< UPRV_LENGTHOF(domainNames
); i
++){
751 bufLen
= (int32_t)strlen(domainNames
[i
]);
752 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
753 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
754 if(U_FAILURE(status
)){
755 errcheckln(status
, "%s failed to convert domainNames[%i].Error: %s",testName
,i
, u_errorName(status
));
758 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
759 //test toASCII with all labels in the string
760 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, FALSE
, TRUE
, func
);
761 if(U_FAILURE(status
)){
762 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
769 void TestIDNA::testCompare(const char* testName
, CompareFunc func
){
773 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
774 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x0000};
775 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
777 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
779 uni0
.append(unicodeIn
[0]);
781 uni0
.append((UChar
)0x0000);
783 uni1
.append(unicodeIn
[1]);
785 uni1
.append((UChar
)0x0000);
787 ascii0
.append(asciiIn
[0]);
789 ascii0
.append((UChar
)0x0000);
791 ascii1
.append(asciiIn
[1]);
793 ascii1
.append((UChar
)0x0000);
795 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
797 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
800 // for every entry in unicodeIn array
801 // prepend www. and append .com
803 source
.append(unicodeIn
[i
]);
805 source
.append((UChar
)0x0000);
806 // a) compare it with itself
807 const UChar
* src
= source
.getBuffer();
808 int32_t srcLen
= u_strlen(src
); //subtract null
810 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
, TRUE
);
812 // b) compare it with asciiIn equivalent
813 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
815 // c) compare it with unicodeIn not equivalent
817 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
819 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
821 // d) compare it with asciiIn not equivalent
823 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
825 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
834 getNextSeperator(UChar
*src
,int32_t srcLength
,
840 *limit
= src
+ i
; // point to null
844 *limit
= src
+ (i
+1); // go past the delimiter
848 // we have not found the delimiter
850 *limit
= src
+srcLength
;
855 for(i
=0;i
<srcLength
;i
++){
857 *limit
= src
+ (i
+1); // go past the delimiter
861 // we have not found the delimiter
863 *limit
= src
+srcLength
;
869 void printPunycodeOutput(){
871 UChar dest
[MAX_DEST_SIZE
];
872 int32_t destCapacity
=MAX_DEST_SIZE
;
876 UBool caseFlags
[MAX_DEST_SIZE
];
878 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
879 ErrorCases errorCase
= errorCases
[i
];
880 UErrorCode status
= U_ZERO_ERROR
;
881 start
= errorCase
.unicode
;
882 int32_t srcLen
= u_strlen(start
);
883 labelLen
= getNextSeperator(start
,srcLen
,&limit
);
885 labelLen
=getNextSeperator(start
,srcLen
-labelLen
,&limit
);
886 int32_t destLen
= u_strToPunycode(dest
,destCapacity
,start
,labelLen
,caseFlags
, &status
);
887 if(U_FAILURE(status
)){
888 printf("u_strToPunycode failed for index %i\n",i
);
891 for(int32_t j
=0; j
<destLen
; j
++){
892 printf("%c",(char)dest
[j
]);
899 void TestIDNA::testErrorCases(const char* IDNToASCIIName
, TestFunc IDNToASCII
,
900 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
901 UChar buf
[MAX_DEST_SIZE
];
904 for(int32_t i
=0;i
< UPRV_LENGTHOF(errorCases
);i
++){
905 ErrorCases errorCase
= errorCases
[i
];
907 if(errorCase
.ascii
!= NULL
){
908 bufLen
= (int32_t)strlen(errorCase
.ascii
);
909 u_charsToUChars(errorCase
.ascii
,buf
, bufLen
+1);
912 memset(buf
,0,U_SIZEOF_UCHAR
*MAX_DEST_SIZE
);
915 if(errorCase
.unicode
[0]!=0){
916 src
= errorCase
.unicode
;
920 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
921 errorCase
.expected
, TRUE
, TRUE
, IDNToASCII
);
922 if(errorCase
.testLabel
==TRUE
){
924 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
925 errorCase
.expected
, FALSE
,TRUE
, IDNToASCII
);
927 if(errorCase
.testToUnicode
==TRUE
){
928 testAPI((src
==NULL
)? NULL
: buf
,src
,
929 IDNToUnicodeName
, errorCase
.useSTD3ASCIIRules
,
930 errorCase
.expected
, TRUE
, TRUE
, IDNToUnicode
);
937 void TestIDNA::testConformance(const char* toASCIIName, TestFunc toASCII,
938 const char* IDNToASCIIName, TestFunc IDNToASCII,
939 const char* IDNToUnicodeName, TestFunc IDNToUnicode,
940 const char* toUnicodeName, TestFunc toUnicode){
941 UChar src[MAX_DEST_SIZE];
943 UChar expected[MAX_DEST_SIZE];
944 int32_t expectedLen = 0;
945 for(int32_t i=0;i< UPRV_LENGTHOF(conformanceTestCases);i++){
946 const char* utf8Chars1 = conformanceTestCases[i].in;
947 int32_t utf8Chars1Len = (int32_t)strlen(utf8Chars1);
948 const char* utf8Chars2 = conformanceTestCases[i].out;
949 int32_t utf8Chars2Len = (utf8Chars2 == NULL) ? 0 : (int32_t)strlen(utf8Chars2);
951 UErrorCode status = U_ZERO_ERROR;
952 u_strFromUTF8(src,MAX_DEST_SIZE,&srcLen,utf8Chars1,utf8Chars1Len,&status);
953 if(U_FAILURE(status)){
954 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
957 if(utf8Chars2 != NULL){
958 u_strFromUTF8(expected,MAX_DEST_SIZE,&expectedLen,utf8Chars2,utf8Chars2Len, &status);
959 if(U_FAILURE(status)){
960 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
965 if(conformanceTestCases[i].expectedStatus != U_ZERO_ERROR){
967 testAPI(src,expected,
968 IDNToASCIIName, FALSE,
969 conformanceTestCases[i].expectedStatus,
971 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
974 testAPI(src,expected,
976 conformanceTestCases[i].expectedStatus, TRUE,
977 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
982 IDNToUnicodeName, FALSE,
983 conformanceTestCases[i].expectedStatus, TRUE, TRUE, IDNToUnicode);
985 toUnicodeName, FALSE,
986 conformanceTestCases[i].expectedStatus, TRUE, TRUE, toUnicode);
992 // test and ascertain
993 // func(func(func(src))) == func(src)
994 void TestIDNA::testChaining(const UChar
* src
,int32_t numIterations
,const char* testName
,
995 UBool useSTD3ASCIIRules
, UBool caseInsensitive
, TestFunc func
){
996 UChar even
[MAX_DEST_SIZE
];
997 UChar odd
[MAX_DEST_SIZE
];
998 UChar expected
[MAX_DEST_SIZE
];
999 int32_t i
=0,evenLen
=0,oddLen
=0,expectedLen
=0;
1000 UErrorCode status
= U_ZERO_ERROR
;
1001 int32_t srcLen
= u_strlen(src
);
1002 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
1003 UParseError parseError
;
1005 // test null-terminated source
1006 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
, options
, &parseError
, &status
);
1007 if(U_FAILURE(status
)){
1008 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1010 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1011 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1012 for(;i
<=numIterations
; i
++){
1014 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1015 if(U_FAILURE(status
)){
1016 errcheckln(status
, "%s null terminated source failed - %s",testName
, u_errorName(status
));
1020 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1021 if(U_FAILURE(status
)){
1022 errln("%s null terminated source failed\n",testName
);
1027 if(caseInsensitive
==TRUE
){
1028 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1029 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1031 errln("Chaining for %s null terminated source failed\n",testName
);
1034 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1035 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1037 errln("Chaining for %s null terminated source failed\n",testName
);
1041 // test null-terminated source
1042 status
= U_ZERO_ERROR
;
1043 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1044 if(U_FAILURE(status
)){
1045 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1047 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1048 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1049 for(;i
<=numIterations
; i
++){
1051 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1052 if(U_FAILURE(status
)){
1053 errcheckln(status
, "%s null terminated source with options set failed - %s",testName
, u_errorName(status
));
1057 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1058 if(U_FAILURE(status
)){
1059 errln("%s null terminated source with options set failed\n",testName
);
1064 if(caseInsensitive
==TRUE
){
1065 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1066 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1068 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1071 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1072 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1074 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1079 // test source with length
1080 status
= U_ZERO_ERROR
;
1081 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1082 if(U_FAILURE(status
)){
1083 errcheckln(status
, "%s null terminated source failed. Error: %s",testName
, u_errorName(status
));
1085 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1086 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1087 for(;i
<=numIterations
; i
++){
1089 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1090 if(U_FAILURE(status
)){
1091 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1095 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1096 if(U_FAILURE(status
)){
1097 errcheckln(status
, "%s source with source length failed - %s",testName
, u_errorName(status
));
1102 if(caseInsensitive
==TRUE
){
1103 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1104 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1106 errln("Chaining for %s source with source length failed\n",testName
);
1109 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1110 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1112 errln("Chaining for %s source with source length failed\n",testName
);
1115 status
= U_ZERO_ERROR
;
1116 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1117 if(U_FAILURE(status
)){
1118 errcheckln(status
, "%s null terminated source with options set failed. Error: %s",testName
, u_errorName(status
));
1120 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1121 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1122 for(;i
<=numIterations
; i
++){
1124 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1125 if(U_FAILURE(status
)){
1126 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1130 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1131 if(U_FAILURE(status
)){
1132 errcheckln(status
, "%s source with source length and options set failed - %s",testName
, u_errorName(status
));
1137 if(caseInsensitive
==TRUE
){
1138 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1139 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1141 errln("Chaining for %s source with source length and options set failed\n",testName
);
1144 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1145 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1147 errln("Chaining for %s source with source length and options set failed\n",testName
);
1151 void TestIDNA::testChaining(const char* toASCIIName
, TestFunc toASCII
,
1152 const char* toUnicodeName
, TestFunc toUnicode
){
1154 UChar buf
[MAX_DEST_SIZE
];
1156 for(i
=0;i
< UPRV_LENGTHOF(asciiIn
); i
++){
1157 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
1158 testChaining(buf
,5,toUnicodeName
, FALSE
, FALSE
, toUnicode
);
1160 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1161 testChaining(unicodeIn
[i
], 5,toASCIIName
, FALSE
, TRUE
, toASCII
);
1166 void TestIDNA::testRootLabelSeparator(const char* testName
, CompareFunc func
,
1167 const char* IDNToASCIIName
, TestFunc IDNToASCII
,
1168 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
1172 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1173 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x002E, /* root label separator */0x0000};
1174 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1176 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
1178 uni0
.append(unicodeIn
[0]);
1180 uni0
.append((UChar
)0x0000);
1182 uni1
.append(unicodeIn
[1]);
1184 uni1
.append((UChar
)0x0000);
1186 ascii0
.append(asciiIn
[0]);
1188 ascii0
.append((UChar
)0x0000);
1190 ascii1
.append(asciiIn
[1]);
1192 ascii1
.append((UChar
)0x0000);
1194 for(i
=0;i
< UPRV_LENGTHOF(unicodeIn
); i
++){
1196 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
1199 // for every entry in unicodeIn array
1200 // prepend www. and append .com
1202 source
.append(unicodeIn
[i
]);
1204 source
.append((UChar
)0x0000);
1206 const UChar
* src
= source
.getBuffer();
1207 int32_t srcLen
= u_strlen(src
); //subtract null
1209 // b) compare it with asciiIn equivalent
1210 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
1212 // a) compare it with itself
1213 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
,TRUE
);
1216 // IDNToASCII comparison
1217 testAPI(src
,buf
,IDNToASCIIName
,FALSE
,U_ZERO_ERROR
,TRUE
, TRUE
, IDNToASCII
);
1218 // IDNToUnicode comparison
1219 testAPI(buf
,src
,IDNToUnicodeName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, IDNToUnicode
);
1221 // c) compare it with unicodeIn not equivalent
1223 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
1225 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
1227 // d) compare it with asciiIn not equivalent
1229 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
1231 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
1236 //---------------------------------------------
1238 //---------------------------------------------
1240 extern IntlTest
*createUTS46Test();
1242 void TestIDNA::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* par
)
1244 if (exec
) logln((UnicodeString
)"TestSuite IDNA API ");
1247 case 0: name
= "TestToASCII"; if (exec
) TestToASCII(); break;
1248 case 1: name
= "TestToUnicode"; if (exec
) TestToUnicode(); break;
1249 case 2: name
= "TestIDNToASCII"; if (exec
) TestIDNToASCII(); break;
1250 case 3: name
= "TestIDNToUnicode"; if (exec
) TestIDNToUnicode(); break;
1251 case 4: name
= "TestCompare"; if (exec
) TestCompare(); break;
1252 case 5: name
= "TestErrorCases"; if (exec
) TestErrorCases(); break;
1253 case 6: name
= "TestChaining"; if (exec
) TestChaining(); break;
1254 case 7: name
= "TestRootLabelSeparator"; if(exec
) TestRootLabelSeparator(); break;
1255 case 8: name
= "TestCompareReferenceImpl"; if(exec
) TestCompareReferenceImpl(); break;
1256 case 9: name
= "TestDataFile"; if(exec
) TestDataFile(); break;
1257 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
1258 case 10: name
= "TestRefIDNA"; if(exec
) TestRefIDNA(); break;
1259 case 11: name
= "TestIDNAMonkeyTest"; if(exec
) TestIDNAMonkeyTest(); break;
1261 case 10: case 11: name
= "skip"; break;
1265 name
= "TestConformanceTestVectors";
1267 logln("TestSuite IDNA conf----"); logln();
1269 callTest(test
, par
);
1276 logln("TestSuite UTS46Test---"); logln();
1277 LocalPointer
<IntlTest
> test(createUTS46Test());
1278 callTest(*test
, par
);
1281 default: name
= ""; break; /*needed to end loop*/
1284 void TestIDNA::TestToASCII(){
1285 testToASCII("uidna_toASCII", uidna_toASCII
);
1287 void TestIDNA::TestToUnicode(){
1288 testToUnicode("uidna_toUnicode", uidna_toUnicode
);
1290 void TestIDNA::TestIDNToASCII(){
1291 testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII
);
1293 void TestIDNA::TestIDNToUnicode(){
1294 testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode
);
1296 void TestIDNA::TestCompare(){
1297 testCompare("uidna_compare",uidna_compare
);
1299 void TestIDNA::TestErrorCases(){
1300 testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII
,
1301 "uidna_IDNToUnicode",uidna_IDNToUnicode
);
1303 void TestIDNA::TestRootLabelSeparator(){
1304 testRootLabelSeparator( "uidna_compare",uidna_compare
,
1305 "uidna_IDNToASCII", uidna_IDNToASCII
,
1306 "uidna_IDNToUnicode",uidna_IDNToUnicode
1309 void TestIDNA::TestChaining(){
1310 testChaining("uidna_toASCII",uidna_toASCII
, "uidna_toUnicode", uidna_toUnicode
);
1314 static const int loopCount
= 100;
1315 static const int maxCharCount
= 20;
1320 static UBool initialized
= FALSE
;
1323 srand((unsigned)time(NULL
));
1326 // Assume rand has at least 12 bits of precision
1328 for (uint32_t i
=0; i
<sizeof(l
); ++i
)
1329 ((char*)&l
)[i
] = (char)((rand() & 0x0FF0) >> 4);
1334 * Return a random integer i where 0 <= i < n.
1335 * A special function that gets random codepoints from planes 0,1,2 and 14
1337 static int32_t rand_uni()
1339 int32_t retVal
= (int32_t)(randul()& 0x3FFFF);
1340 if(retVal
>= 0x30000){
1346 static int32_t randi(int32_t n
){
1347 return (int32_t) (randul() % (n
+1));
1350 void getTestSource(UnicodeString
& fillIn
) {
1352 int32_t charCount
= (randi(maxCharCount
) + 1);
1353 while (i
<charCount
) {
1354 int32_t codepoint
= rand_uni();
1355 if(codepoint
== 0x0000){
1358 fillIn
.append((UChar32
)codepoint
);
1364 UnicodeString
TestIDNA::testCompareReferenceImpl(UnicodeString
& src
,
1365 TestFunc refIDNA
, const char* refIDNAName
,
1366 TestFunc uIDNA
, const char* uIDNAName
,
1369 const UChar
* srcUChars
= src
.getBuffer();
1370 UChar exp
[MAX_DEST_SIZE
]={0};
1371 int32_t expCap
= MAX_DEST_SIZE
, expLen
=0;
1372 UErrorCode expStatus
= U_ZERO_ERROR
;
1373 UParseError parseError
;
1375 logln("Comparing "+ UnicodeString(refIDNAName
)
1376 + " with "+ UnicodeString(uIDNAName
)
1377 +" for input: " + prettify(srcUChars
));
1379 expLen
= refIDNA(srcUChars
, src
.length()-1, exp
, expCap
,
1380 options
, &parseError
, &expStatus
);
1382 UChar got
[MAX_DEST_SIZE
]={0};
1383 int32_t gotCap
= MAX_DEST_SIZE
, gotLen
=0;
1384 UErrorCode gotStatus
= U_ZERO_ERROR
;
1386 gotLen
= uIDNA(srcUChars
, src
.length()-1, got
, gotCap
,
1387 options
, &parseError
, &gotStatus
);
1389 if(expStatus
!= gotStatus
){
1390 errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName
)
1391 + " with " + UnicodeString(uIDNAName
)
1392 + " Expected: " + UnicodeString(u_errorName(expStatus
))
1393 + " Got: " + UnicodeString(u_errorName(gotStatus
))
1394 + " for Source: "+ prettify(srcUChars
)
1395 + " Options: " + options
);
1396 return UnicodeString("");
1399 // now we know that both implementations yielded same error
1400 if(U_SUCCESS(expStatus
)){
1401 // compare the outputs if status == U_ZERO_ERROR
1402 if(u_strCompare(exp
, expLen
, got
, gotLen
, TRUE
) != 0){
1403 errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName
)
1404 + " with " + UnicodeString(uIDNAName
)
1405 + " Expected: " + prettify(UnicodeString(exp
, expLen
))
1406 + " Got: " + prettify(UnicodeString(got
, gotLen
))
1407 + " for Source: "+ prettify(srcUChars
)
1408 + " Options: " + options
);
1410 return UnicodeString(exp
, expLen
);
1413 logln("Got the same error while comparing "
1414 + UnicodeString(refIDNAName
)
1415 + " with "+ UnicodeString(uIDNAName
)
1416 +" for input: " + prettify(srcUChars
));
1418 return UnicodeString("");
1421 void TestIDNA::testCompareReferenceImpl(const UChar
* src
, int32_t srcLen
){
1422 UnicodeString
label(src
,srcLen
);
1423 label
.append((UChar
)0x0000);
1425 //test idnaref_toASCII and idnare
1426 UnicodeString asciiLabel
= testCompareReferenceImpl(label
,
1427 idnaref_toASCII
, "idnaref_toASCII",
1428 uidna_toASCII
, "uidna_toASCII",
1429 UIDNA_ALLOW_UNASSIGNED
);
1430 testCompareReferenceImpl(label
,
1431 idnaref_toASCII
, "idnaref_toASCII",
1432 uidna_toASCII
, "uidna_toASCII",
1434 testCompareReferenceImpl(label
,
1435 idnaref_toASCII
, "idnaref_toASCII",
1436 uidna_toASCII
, "uidna_toASCII",
1437 UIDNA_USE_STD3_RULES
);
1438 testCompareReferenceImpl(label
,
1439 idnaref_toASCII
, "idnaref_toASCII",
1440 uidna_toASCII
, "uidna_toASCII",
1441 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1443 if(asciiLabel
.length()!=0){
1444 asciiLabel
.append((UChar
)0x0000);
1447 testCompareReferenceImpl(asciiLabel
,
1448 idnaref_toUnicode
, "idnaref_toUnicode",
1449 uidna_toUnicode
, "uidna_toUnicode",
1450 UIDNA_ALLOW_UNASSIGNED
);
1451 testCompareReferenceImpl(asciiLabel
,
1452 idnaref_toUnicode
, "idnaref_toUnicode",
1453 uidna_toUnicode
, "uidna_toUnicode",
1455 testCompareReferenceImpl(asciiLabel
,
1456 idnaref_toUnicode
, "idnaref_toUnicode",
1457 uidna_toUnicode
, "uidna_toUnicode",
1458 UIDNA_USE_STD3_RULES
);
1459 testCompareReferenceImpl(asciiLabel
,
1460 idnaref_toUnicode
, "idnaref_toUnicode",
1461 uidna_toUnicode
, "uidna_toUnicode",
1462 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1466 const char* failures
[] ={
1467 "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1468 "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1471 void TestIDNA::TestIDNAMonkeyTest(){
1472 UnicodeString source
;
1473 UErrorCode status
= U_ZERO_ERROR
;
1476 getInstance(status
); // Init prep
1477 if (U_FAILURE(status
)) {
1478 dataerrln("Test could not initialize. Got %s", u_errorName(status
));
1482 for(i
=0; i
<loopCount
; i
++){
1484 getTestSource(source
);
1485 source
.append((UChar
)0x0000);
1486 const UChar
* src
= source
.getBuffer();
1487 testCompareReferenceImpl(src
,source
.length()-1);
1488 testCompareReferenceImpl(src
,source
.length()-1);
1492 for (i
=0; i
<UPRV_LENGTHOF(failures
); i
++){
1494 source
.append( UnicodeString(failures
[i
], -1, US_INV
) );
1495 source
= source
.unescape();
1496 source
.append((UChar
)0x0000);
1497 const UChar
*src
= source
.getBuffer();
1498 testCompareReferenceImpl(src
,source
.length()-1);
1499 //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1504 source
.append(UNICODE_STRING_SIMPLE("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C"));
1505 debug(source
.getBuffer(),source
.length(),UIDNA_ALLOW_UNASSIGNED
);
1507 { // test deletion of code points
1508 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
);
1509 source
= source
.unescape();
1510 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
);
1511 expected
= expected
.unescape();
1512 UnicodeString
ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1513 ascii
.append((UChar
)0x0000);
1514 testAPI(source
.getBuffer(),ascii
.getBuffer(), "uidna_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, uidna_toASCII
);
1516 testAPI(source
.getBuffer(),ascii
.getBuffer(), "idnaref_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, idnaref_toASCII
);
1518 testCompareReferenceImpl(source
.getBuffer(), source
.length()-1);
1523 void TestIDNA::TestCompareReferenceImpl(){
1525 UChar src
[2] = {0,0};
1530 UErrorCode dataStatus
= U_ZERO_ERROR
;
1531 loadTestData(dataStatus
);
1532 if(U_FAILURE(dataStatus
)) {
1533 dataerrln("Couldn't load test data: %s\n", u_errorName(dataStatus
)); // save us from thousands and thousands of errors
1538 for (int32_t i
= 0; i
<= 0x10FFFF; i
++){
1539 if (quick
== TRUE
&& i
> 0x0FFF){
1543 // jump to E0000, no characters assigned in plain 3 to plain 13 as of Unicode 6.0
1547 src
[0] = U16_LEAD(i
);
1548 src
[1] = U16_TRAIL(i
);
1555 testCompareReferenceImpl(src
, srcLen
);
1559 void TestIDNA::TestRefIDNA(){
1560 UErrorCode status
= U_ZERO_ERROR
;
1561 getInstance(status
); // Init prep
1562 if (U_FAILURE(status
)) {
1563 if (status
== U_FILE_ACCESS_ERROR
) {
1564 dataerrln("Test could not initialize. Got %s", u_errorName(status
));
1569 testToASCII("idnaref_toASCII", idnaref_toASCII
);
1570 testToUnicode("idnaref_toUnicode", idnaref_toUnicode
);
1571 testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII
);
1572 testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode
);
1573 testCompare("idnaref_compare",idnaref_compare
);
1574 testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII
,
1575 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
);
1576 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1578 testRootLabelSeparator( "idnaref_compare",idnaref_compare
,
1579 "idnaref_IDNToASCII", idnaref_IDNToASCII
,
1580 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1582 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1586 void TestIDNA::TestDataFile(){
1589 TestIDNA::~TestIDNA(){
1596 NamePrepTransform
* TestIDNA::gPrep
= NULL
;
1598 NamePrepTransform
* TestIDNA::getInstance(UErrorCode
& status
){
1599 if(TestIDNA::gPrep
== NULL
){
1600 UParseError parseError
;
1601 TestIDNA::gPrep
= NamePrepTransform::createInstance(parseError
, status
);
1602 if(TestIDNA::gPrep
==NULL
){
1603 //status = U_MEMORY_ALLOCATION_ERROR;
1607 return TestIDNA::gPrep
;
1610 #endif /* #if !UCONFIG_NO_IDNA */