2 *******************************************************************************
4 * Copyright (C) 2003-2008, 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/ustring.h"
26 #include "unicode/usprep.h"
27 #include "unicode/uniset.h"
31 #include "unicode/putil.h"
34 static const UChar unicodeIn
[][41] ={
36 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 0x0644,
37 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 0x061F, 0x0000
40 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587,
44 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 0x0074,
45 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 0x00ED, 0x010D,
46 0x0065, 0x0073, 0x006B, 0x0079, 0x0000
49 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 0x05D8,
50 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 0x05DD, 0x05E2,
51 0x05D1, 0x05E8, 0x05D9, 0x05EA, 0x0000
54 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 0x094D,
55 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 0x0928, 0x0939,
56 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 0x0915, 0x0924, 0x0947,
57 0x0939, 0x0948, 0x0902, 0x0000
60 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 0x3092,
61 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 0x306E, 0x304B,
66 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
67 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
68 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C, 0x0000
72 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 0x043E,
73 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 0x043E, 0x0440,
74 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 0x0441, 0x0441, 0x043A,
78 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 0x0070,
79 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 0x006D, 0x0070,
80 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 0x0065, 0x0068, 0x0061,
81 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 0x006E, 0x0045, 0x0073, 0x0070,
82 0x0061, 0x00F1, 0x006F, 0x006C, 0x0000
85 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587,
89 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 0x006B,
90 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 0x0063, 0x0068,
91 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 0x1EBF, 0x006E, 0x0067,
92 0x0056, 0x0069, 0x1EC7, 0x0074, 0x0000
95 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F, 0x0000
98 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 0x0074,
99 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 0x002D, 0x004D,
100 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053, 0x0000
103 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 0x006F,
104 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 0x0079, 0x002D,
105 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 0x6240, 0x0000
108 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032, 0x0000
111 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 0x3059,
112 0x308B, 0x0035, 0x79D2, 0x524D, 0x0000
115 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0,
119 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067, 0x0000
121 // test non-BMP code points
123 0xD800, 0xDF00, 0xD800, 0xDF01, 0xD800, 0xDF02, 0xD800, 0xDF03, 0xD800, 0xDF05,
124 0xD800, 0xDF06, 0xD800, 0xDF07, 0xD800, 0xDF09, 0xD800, 0xDF0A, 0xD800, 0xDF0B,
128 0xD800, 0xDF0D, 0xD800, 0xDF0C, 0xD800, 0xDF1E, 0xD800, 0xDF0F, 0xD800, 0xDF16,
129 0xD800, 0xDF15, 0xD800, 0xDF14, 0xD800, 0xDF12, 0xD800, 0xDF10, 0xD800, 0xDF20,
135 0x03b5, 0x03bb, 0x03bb, 0x03b7, 0x03bd, 0x03b9, 0x03ba, 0x03ac
139 0x0062, 0x006f, 0x006e, 0x0121, 0x0075, 0x0073, 0x0061, 0x0127,
144 0x043f, 0x043e, 0x0447, 0x0435, 0x043c, 0x0443, 0x0436, 0x0435,
145 0x043e, 0x043d, 0x0438, 0x043d, 0x0435, 0x0433, 0x043e, 0x0432,
146 0x043e, 0x0440, 0x044f, 0x0442, 0x043f, 0x043e, 0x0440, 0x0443,
147 0x0441, 0x0441, 0x043a, 0x0438
155 static const char *asciiIn
[] = {
156 "xn--egbpdaj6bu4bxfgehfvwxn",
157 "xn--ihqwcrb4cv8a8dqg056pqjye",
158 "xn--Proprostnemluvesky-uyb24dma41a",
159 "xn--4dbcagdahymbxekheh6e0a7fei0b",
160 "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd",
161 "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa",
162 /* "xn--989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",*/
163 "xn--b1abfaaepdrnnbgefbaDotcwatmq2g4l",
164 "xn--PorqunopuedensimplementehablarenEspaol-fmd56a",
165 "xn--ihqwctvzc91f659drss3x8bo0yb",
166 "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g",
167 "xn--3B-ww4c5e180e575a65lsy2b",
168 "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n",
169 "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b",
170 "xn--2-u9tlzr9756bt3uc0v",
171 "xn--MajiKoi5-783gue6qz075azm5e",
172 "xn--de-jg4avhby1noc0d",
173 "xn--d9juau41awczczp",
175 "XN--db8CBHEJLGH4E0AL",
176 "xn--hxargifdar", // Greek
177 "xn--bonusaa-5bb1da", // Maltese
178 "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l", // Russian (Cyrillic)
182 static const char *domainNames
[] = {
183 "slip129-37-118-146.nc.us.ibm.net",
184 "saratoga.pe.utexas.edu",
185 "dial-120-45.ots.utexas.edu",
186 "woo-085.dorms.waller.net",
187 "hd30-049.hil.compuserve.com",
188 "pem203-31.pe.ttu.edu",
189 "56K-227.MaxTNT3.pdq.net",
190 "dial-36-2.ots.utexas.edu",
191 "slip129-37-23-152.ga.us.ibm.net",
192 "ts45ip119.cadvision.com",
193 "sdn-ts-004txaustP05.dialsprint.net",
194 "bar-tnt1s66.erols.com",
195 "101.st-louis-15.mo.dial-access.att.net",
197 "dial-13-2.ots.utexas.edu",
198 "net-redynet29.datamarkets.com.ar",
199 "ccs-shiva28.reacciun.net.ve",
200 "7.houston-11.tx.dial-access.att.net",
201 "ingw129-37-120-26.mo.us.ibm.net",
202 "dialup6.austintx.com",
204 "slip129-37-119-194.nc.us.ibm.net",
205 "cs7.dillons.co.uk.203.119.193.in-addr.arpa",
206 "swprd1.innovplace.saskatoon.sk.ca",
207 "bikini.bologna.maraut.it",
208 "node91.subnet159-198-79.baxter.com",
209 "cust19.max5.new-york.ny.ms.uu.net",
210 "balexander.slip.andrew.cmu.edu",
211 "pool029.max2.denver.co.dynip.alter.net",
212 "cust49.max9.new-york.ny.ms.uu.net",
213 "s61.abq-dialin2.hollyberry.com",
214 "\\u0917\\u0928\\u0947\\u0936.sanjose.ibm.com", //':'(0x003a) produces U_IDNA_STD3_ASCII_RULES_ERROR
216 // "www.\\u00E0\\u00B3\\u00AF.com",//' ' (0x0020) produces U_IDNA_STD3_ASCII_RULES_ERROR
217 "www.\\u00C2\\u00A4.com",
218 "www.\\u00C2\\u00A3.com",
219 // "\\u0025", //'%' (0x0025) produces U_IDNA_STD3_ASCII_RULES_ERROR
220 // "\\u005C\\u005C", //'\' (0x005C) produces U_IDNA_STD3_ASCII_RULES_ERROR
226 // These yeild U_IDNA_PROHIBITED_ERROR
227 //"\\u00CF\\u0082.com",
228 //"\\u00CE\\u00B2\\u00C3\\u009Fss.com",
229 //"\\u00E2\\u0098\\u00BA.com",
230 "\\u00C3\\u00BC.com",
234 typedef struct ErrorCases ErrorCases
;
236 static const struct ErrorCases
{
241 UBool useSTD3ASCIIRules
;
248 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
249 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
250 0x070F,/*prohibited*/
251 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
252 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
255 "www.XN--8mb5595fsoa28orucya378bqre2tcwop06c5qbw82a1rffmae0361dea96b.com",
256 U_IDNA_PROHIBITED_ERROR
,
262 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
263 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
264 0x0221, 0x0234/*Unassigned code points*/,
265 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
268 "www.XN--6lA2Bz548Fj1GuA391Bf1Gb1N59Ab29A7iA.com",
270 U_IDNA_UNASSIGNED_ERROR
,
275 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
276 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
277 0x0644, 0x064A, 0x0647,/*Arabic code points. Cannot mix RTL with LTR*/
278 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
279 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
282 "www.xn--ghBGI4851OiyA33VqrD6Az86C4qF83CtRv93D5xBk15AzfG0nAgA0578DeA71C.com",
283 U_IDNA_CHECK_BIDI_ERROR
,
288 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
289 /* labels cannot begin with an HYPHEN */
290 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
292 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
293 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
297 "www.xn----b95Ew8SqA315Ao5FbuMlnNmhA.com",
298 U_IDNA_STD3_ASCII_RULES_ERROR
,
303 /* correct ACE-prefix followed by unicode */
304 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
305 0x0078, 0x006e, 0x002d,0x002d, /* ACE Prefix */
306 0x002D, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
308 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
309 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
313 /* wrong ACE-prefix followed by valid ACE-encoded ASCII */
314 "www.XY-----b91I0V65S96C2A355Cw1E5yCeQr19CsnP1mFfmAE0361DeA96B.com",
315 U_IDNA_ACE_PREFIX_ERROR
,
318 /* cannot verify U_IDNA_VERIFICATION_ERROR */
322 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
323 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 0xC774,
324 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 0xB2E4, 0xBA74,
325 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C,
326 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
329 "www.xn--989AoMsVi5E83Db1D2A355Cv1E0vAk1DwRv93D5xBh15A0Dt30A5JpSD879Ccm6FeA98C.com",
330 U_IDNA_LABEL_TOO_LONG_ERROR
,
336 0x0077, 0x0077, 0x0077, 0x002e, /* www. */
337 0x0030, 0x0644, 0x064A, 0x0647, 0x0031, /* Arabic code points squashed between EN codepoints */
338 0x002e, 0x0063, 0x006f, 0x006d, /* com. */
341 "www.xn--01-tvdmo.com",
342 U_IDNA_CHECK_BIDI_ERROR
,
348 0x0077, 0x0077, 0x0077, 0x002e, // www.
349 0x206C, 0x0644, 0x064A, 0x0647, 0x206D, // Arabic code points squashed between BN codepoints
350 0x002e, 0x0063, 0x006f, 0x006d, // com.
353 "www.XN--ghbgi278xia.com",
354 U_IDNA_PROHIBITED_ERROR
,
359 0x0077, 0x0077, 0x0077, 0x002e, // www.
360 0x002D, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, // HYPHEN at the start of label
361 0x002e, 0x0063, 0x006f, 0x006d, // com.
365 U_IDNA_STD3_ASCII_RULES_ERROR
,
370 0x0077, 0x0077, 0x0077, 0x002e, // www.
371 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x002D, // HYPHEN at the end of the label
372 0x002e, 0x0063, 0x006f, 0x006d, // com.
376 U_IDNA_STD3_ASCII_RULES_ERROR
,
381 0x0077, 0x0077, 0x0077, 0x002e, // www.
382 0x0041, 0x0042, 0x0043, 0x0044, 0x0045,0x0040, // Containing non LDH code point
383 0x002e, 0x0063, 0x006f, 0x006d, // com.
387 U_IDNA_STD3_ASCII_RULES_ERROR
,
392 0x0077, 0x0077, 0x0077, 0x002e, // www.
394 0x002e, 0x0063, 0x006f, 0x006d, // com.
398 U_IDNA_ZERO_LENGTH_LABEL_ERROR
,
404 U_ILLEGAL_ARGUMENT_ERROR
,
412 #define MAX_DEST_SIZE 300
414 void TestIDNA::debug(const UChar
* src
, int32_t srcLength
, int32_t options
){
415 UParseError parseError
;
416 UErrorCode transStatus
= U_ZERO_ERROR
;
417 UErrorCode prepStatus
= U_ZERO_ERROR
;
418 NamePrepTransform
* trans
= NamePrepTransform::createInstance(parseError
,transStatus
);
419 int32_t prepOptions
= (((options
& UIDNA_ALLOW_UNASSIGNED
) != 0) ? USPREP_ALLOW_UNASSIGNED
: 0);
420 UStringPrepProfile
* prep
= usprep_open(NULL
,"uidna",&prepStatus
);
421 UChar
*transOut
=NULL
, *prepOut
=NULL
;
422 int32_t transOutLength
=0, prepOutLength
=0;
425 transOutLength
= trans
->process(src
,srcLength
,transOut
, 0, prepOptions
>0, &parseError
, transStatus
);
426 if( transStatus
== U_BUFFER_OVERFLOW_ERROR
){
427 transStatus
= U_ZERO_ERROR
;
428 transOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* transOutLength
);
429 transOutLength
= trans
->process(src
,srcLength
,transOut
, transOutLength
, prepOptions
>0, &parseError
, transStatus
);
432 prepOutLength
= usprep_prepare(prep
, src
, srcLength
, prepOut
, 0, prepOptions
, &parseError
, &prepStatus
);
434 if( prepStatus
== U_BUFFER_OVERFLOW_ERROR
){
435 prepStatus
= U_ZERO_ERROR
;
436 prepOut
= (UChar
*) malloc(U_SIZEOF_UCHAR
* prepOutLength
);
437 prepOutLength
= usprep_prepare(prep
, src
, srcLength
, prepOut
, prepOutLength
, prepOptions
, &parseError
, &prepStatus
);
440 if(UnicodeString(transOut
,transOutLength
)!= UnicodeString(prepOut
, prepOutLength
)){
441 errln("Failed. Expected: " + prettify(UnicodeString(transOut
, transOutLength
))
442 + " Got: " + prettify(UnicodeString(prepOut
,prepOutLength
)));
450 void TestIDNA::testAPI(const UChar
* src
, const UChar
* expected
, const char* testName
,
451 UBool useSTD3ASCIIRules
,UErrorCode expectedStatus
,
452 UBool doCompare
, UBool testUnassigned
, TestFunc func
, UBool testSTD3ASCIIRules
){
454 UErrorCode status
= U_ZERO_ERROR
;
455 UChar destStack
[MAX_DEST_SIZE
];
458 int32_t expectedLen
= (expected
!= NULL
) ? u_strlen(expected
) : 0;
459 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
460 UParseError parseError
;
465 tSrcLen
= u_strlen(src
);
466 tSrc
=(UChar
*) malloc( U_SIZEOF_UCHAR
* tSrcLen
);
467 memcpy(tSrc
,src
,tSrcLen
* U_SIZEOF_UCHAR
);
470 // test null-terminated source and return value of number of UChars required
471 destLen
= func(src
,-1,NULL
,0,options
, &parseError
, &status
);
472 if(status
== U_BUFFER_OVERFLOW_ERROR
){
473 status
= U_ZERO_ERROR
; // reset error code
474 if(destLen
+1 < MAX_DEST_SIZE
){
476 destLen
= func(src
,-1,dest
,destLen
+1,options
, &parseError
, &status
);
477 // TODO : compare output with expected
478 if(U_SUCCESS(status
) && expectedStatus
!= U_IDNA_STD3_ASCII_RULES_ERROR
&& (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
479 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source. Expected : "
480 + prettify(UnicodeString(expected
,expectedLen
))
481 + " Got: " + prettify(UnicodeString(dest
,destLen
))
485 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
489 if(status
!= expectedStatus
){
490 errln( "Did not get the expected error for "+
491 UnicodeString(testName
)+
492 " null terminated source. Expected: " +UnicodeString(u_errorName(expectedStatus
))
493 + " Got: "+ UnicodeString(u_errorName(status
))
494 + " Source: " + prettify(UnicodeString(src
))
500 status
= U_ZERO_ERROR
;
501 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
502 if(status
== U_BUFFER_OVERFLOW_ERROR
){
503 status
= U_ZERO_ERROR
; // reset error code
504 if(destLen
+1 < MAX_DEST_SIZE
){
506 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
507 // TODO : compare output with expected
508 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
509 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
510 errln("Did not get the expected result for "+UnicodeString(testName
) +
511 " null terminated source "+ prettify(src
) +
512 " with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
))+
513 "Got: " + prettify(UnicodeString(dest
,destLen
)));
515 debug(src
,-1,options
| UIDNA_ALLOW_UNASSIGNED
);
519 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
522 //testing query string
523 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
524 errln( "Did not get the expected error for "+
525 UnicodeString(testName
)+
526 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
527 + " Got: "+ UnicodeString(u_errorName(status
))
528 + " Source: " + prettify(UnicodeString(src
))
533 status
= U_ZERO_ERROR
;
535 // test source with lengthand return value of number of UChars required
536 destLen
= func(tSrc
, tSrcLen
, NULL
,0,options
, &parseError
, &status
);
537 if(status
== U_BUFFER_OVERFLOW_ERROR
){
538 status
= U_ZERO_ERROR
; // reset error code
539 if(destLen
+1 < MAX_DEST_SIZE
){
541 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
, &parseError
, &status
);
542 // TODO : compare output with expected
543 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
544 errln("Did not get the expected result for %s with source length.\n",testName
);
547 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
551 if(status
!= expectedStatus
){
552 errln( "Did not get the expected error for "+
553 UnicodeString(testName
)+
554 " with source length. Expected: " +UnicodeString(u_errorName(expectedStatus
))
555 + " Got: "+ UnicodeString(u_errorName(status
))
556 + " Source: " + prettify(UnicodeString(src
))
560 status
= U_ZERO_ERROR
;
562 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
564 if(status
== U_BUFFER_OVERFLOW_ERROR
){
565 status
= U_ZERO_ERROR
; // reset error code
566 if(destLen
+1 < MAX_DEST_SIZE
){
568 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
569 // TODO : compare output with expected
570 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
571 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
574 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
577 //testing query string
578 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
579 errln( "Did not get the expected error for "+
580 UnicodeString(testName
)+
581 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
582 + " Got: "+ UnicodeString(u_errorName(status
))
583 + " Source: " + prettify(UnicodeString(src
))
588 status
= U_ZERO_ERROR
;
589 if(testSTD3ASCIIRules
==TRUE
){
590 destLen
= func(src
,-1,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
591 if(status
== U_BUFFER_OVERFLOW_ERROR
){
592 status
= U_ZERO_ERROR
; // reset error code
593 if(destLen
+1 < MAX_DEST_SIZE
){
595 destLen
= func(src
,-1,dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
596 // TODO : compare output with expected
597 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
598 //errln("Did not get the expected result for %s null terminated source with both options set.\n",testName);
599 errln("Did not get the expected result for "+UnicodeString(testName
) +" null terminated source with both options set. Expected: "+ prettify(UnicodeString(expected
,expectedLen
)));
603 errln( "%s null terminated source failed. Requires destCapacity > 300\n",testName
);
606 //testing query string
607 if(status
!= expectedStatus
){
608 errln( "Did not get the expected error for "+
609 UnicodeString(testName
)+
610 " null terminated source with options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
611 + " Got: "+ UnicodeString(u_errorName(status
))
612 + " Source: " + prettify(UnicodeString(src
))
616 status
= U_ZERO_ERROR
;
618 destLen
= func(tSrc
,tSrcLen
,NULL
,0,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
620 if(status
== U_BUFFER_OVERFLOW_ERROR
){
621 status
= U_ZERO_ERROR
; // reset error code
622 if(destLen
+1 < MAX_DEST_SIZE
){
624 destLen
= func(src
,u_strlen(src
),dest
,destLen
+1,options
| UIDNA_USE_STD3_RULES
, &parseError
, &status
);
625 // TODO : compare output with expected
626 if(U_SUCCESS(status
) && (doCompare
==TRUE
) && u_strCaseCompare(dest
,destLen
, expected
,expectedLen
,0,&status
)!=0){
627 errln("Did not get the expected result for %s with source length and both options set.\n",testName
);
630 errln( "%s with source length failed. Requires destCapacity > 300\n",testName
);
633 //testing query string
634 if(status
!= expectedStatus
&& expectedStatus
!= U_IDNA_UNASSIGNED_ERROR
){
635 errln( "Did not get the expected error for "+
636 UnicodeString(testName
)+
637 " with source length and options set. Expected: " +UnicodeString(u_errorName(expectedStatus
))
638 + " Got: "+ UnicodeString(u_errorName(status
))
639 + " Source: " + prettify(UnicodeString(src
))
646 void TestIDNA::testCompare(const UChar
* s1
, int32_t s1Len
,
647 const UChar
* s2
, int32_t s2Len
,
648 const char* testName
, CompareFunc func
,
651 UErrorCode status
= U_ZERO_ERROR
;
652 int32_t retVal
= func(s1
,-1,s2
,-1,UIDNA_DEFAULT
,&status
);
654 if(isEqual
==TRUE
&& retVal
!=0){
655 errln("Did not get the expected result for %s with null termniated strings.\n",testName
);
657 if(U_FAILURE(status
)){
658 errln( "%s null terminated source failed. Error: %s\n", testName
,u_errorName(status
));
661 status
= U_ZERO_ERROR
;
662 retVal
= func(s1
,-1,s2
,-1,UIDNA_ALLOW_UNASSIGNED
,&status
);
664 if(isEqual
==TRUE
&& retVal
!=0){
665 errln("Did not get the expected result for %s with null termniated strings with options set.\n", testName
);
667 if(U_FAILURE(status
)){
668 errln( "%s null terminated source and options set failed. Error: %s\n",testName
, u_errorName(status
));
671 status
= U_ZERO_ERROR
;
672 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_DEFAULT
,&status
);
674 if(isEqual
==TRUE
&& retVal
!=0){
675 errln("Did not get the expected result for %s with string length.\n",testName
);
677 if(U_FAILURE(status
)){
678 errln( "%s with string length. Error: %s\n",testName
, u_errorName(status
));
681 status
= U_ZERO_ERROR
;
682 retVal
= func(s1
,s1Len
,s2
,s2Len
,UIDNA_ALLOW_UNASSIGNED
,&status
);
684 if(isEqual
==TRUE
&& retVal
!=0){
685 errln("Did not get the expected result for %s with string length and options set.\n",testName
);
687 if(U_FAILURE(status
)){
688 errln( "%s with string length and options set. Error: %s\n", u_errorName(status
), testName
);
692 void TestIDNA::testToASCII(const char* testName
, TestFunc func
){
695 UChar buf
[MAX_DEST_SIZE
];
697 for(i
=0;i
< (int32_t)(sizeof(unicodeIn
)/sizeof(unicodeIn
[0])); i
++){
698 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
699 testAPI(unicodeIn
[i
], buf
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
704 void TestIDNA::testToUnicode(const char* testName
, TestFunc func
){
707 UChar buf
[MAX_DEST_SIZE
];
709 for(i
=0;i
< (int32_t)(sizeof(asciiIn
)/sizeof(asciiIn
[0])); i
++){
710 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
711 testAPI(buf
,unicodeIn
[i
],testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
716 void TestIDNA::testIDNToUnicode(const char* testName
, TestFunc func
){
718 UChar buf
[MAX_DEST_SIZE
];
719 UChar expected
[MAX_DEST_SIZE
];
720 UErrorCode status
= U_ZERO_ERROR
;
722 UParseError parseError
;
723 for(i
=0;i
< (int32_t)(sizeof(domainNames
)/sizeof(domainNames
[0])); i
++){
724 bufLen
= (int32_t)strlen(domainNames
[i
]);
725 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
726 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
727 if(U_FAILURE(status
)){
728 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
, i
, u_errorName(status
));
731 testAPI(buf
,expected
,testName
,FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
732 //test toUnicode with all labels in the string
733 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
734 if(U_FAILURE(status
)){
735 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
742 void TestIDNA::testIDNToASCII(const char* testName
, TestFunc func
){
744 UChar buf
[MAX_DEST_SIZE
];
745 UChar expected
[MAX_DEST_SIZE
];
746 UErrorCode status
= U_ZERO_ERROR
;
748 UParseError parseError
;
749 for(i
=0;i
< (int32_t)(sizeof(domainNames
)/sizeof(domainNames
[0])); i
++){
750 bufLen
= (int32_t)strlen(domainNames
[i
]);
751 bufLen
= u_unescape(domainNames
[i
],buf
, bufLen
+1);
752 func(buf
,bufLen
,expected
,MAX_DEST_SIZE
, UIDNA_ALLOW_UNASSIGNED
, &parseError
,&status
);
753 if(U_FAILURE(status
)){
754 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
757 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, func
);
758 //test toASCII with all labels in the string
759 testAPI(buf
,expected
,testName
, FALSE
,U_ZERO_ERROR
, FALSE
, TRUE
, func
);
760 if(U_FAILURE(status
)){
761 errln( "%s failed to convert domainNames[%i].Error: %s \n",testName
,i
, u_errorName(status
));
768 void TestIDNA::testCompare(const char* testName
, CompareFunc func
){
772 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
773 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x0000};
774 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
776 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
778 uni0
.append(unicodeIn
[0]);
780 uni0
.append((UChar
)0x0000);
782 uni1
.append(unicodeIn
[1]);
784 uni1
.append((UChar
)0x0000);
786 ascii0
.append(asciiIn
[0]);
788 ascii0
.append((UChar
)0x0000);
790 ascii1
.append(asciiIn
[1]);
792 ascii1
.append((UChar
)0x0000);
794 for(i
=0;i
< (int32_t)(sizeof(unicodeIn
)/sizeof(unicodeIn
[0])); i
++){
796 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
799 // for every entry in unicodeIn array
800 // prepend www. and append .com
802 source
.append(unicodeIn
[i
]);
804 source
.append((UChar
)0x0000);
805 // a) compare it with itself
806 const UChar
* src
= source
.getBuffer();
807 int32_t srcLen
= u_strlen(src
); //subtract null
809 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
, TRUE
);
811 // b) compare it with asciiIn equivalent
812 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
814 // c) compare it with unicodeIn not equivalent
816 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
818 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
820 // d) compare it with asciiIn not equivalent
822 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
824 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
833 getNextSeperator(UChar
*src
,int32_t srcLength
,
839 *limit
= src
+ i
; // point to null
843 *limit
= src
+ (i
+1); // go past the delimiter
847 // we have not found the delimiter
849 *limit
= src
+srcLength
;
854 for(i
=0;i
<srcLength
;i
++){
856 *limit
= src
+ (i
+1); // go past the delimiter
860 // we have not found the delimiter
862 *limit
= src
+srcLength
;
868 void printPunycodeOutput(){
870 UChar dest
[MAX_DEST_SIZE
];
871 int32_t destCapacity
=MAX_DEST_SIZE
;
875 UBool caseFlags
[MAX_DEST_SIZE
];
877 for(int32_t i
=0;i
< sizeof(errorCases
)/sizeof(errorCases
[0]);i
++){
878 ErrorCases errorCase
= errorCases
[i
];
879 UErrorCode status
= U_ZERO_ERROR
;
880 start
= errorCase
.unicode
;
881 int32_t srcLen
= u_strlen(start
);
882 labelLen
= getNextSeperator(start
,srcLen
,&limit
);
884 labelLen
=getNextSeperator(start
,srcLen
-labelLen
,&limit
);
885 int32_t destLen
= u_strToPunycode(dest
,destCapacity
,start
,labelLen
,caseFlags
, &status
);
886 if(U_FAILURE(status
)){
887 printf("u_strToPunycode failed for index %i\n",i
);
890 for(int32_t j
=0; j
<destLen
; j
++){
891 printf("%c",(char)dest
[j
]);
898 void TestIDNA::testErrorCases(const char* IDNToASCIIName
, TestFunc IDNToASCII
,
899 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
900 UChar buf
[MAX_DEST_SIZE
];
903 for(int32_t i
=0;i
< (int32_t)(sizeof(errorCases
)/sizeof(errorCases
[0]));i
++){
904 ErrorCases errorCase
= errorCases
[i
];
906 if(errorCase
.ascii
!= NULL
){
907 bufLen
= (int32_t)strlen(errorCase
.ascii
);
908 u_charsToUChars(errorCase
.ascii
,buf
, bufLen
+1);
911 memset(buf
,0,U_SIZEOF_UCHAR
*MAX_DEST_SIZE
);
914 if(errorCase
.unicode
[0]!=0){
915 src
= errorCase
.unicode
;
919 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
920 errorCase
.expected
, TRUE
, TRUE
, IDNToASCII
);
921 if(errorCase
.testLabel
==TRUE
){
923 IDNToASCIIName
, errorCase
.useSTD3ASCIIRules
,
924 errorCase
.expected
, FALSE
,TRUE
, IDNToASCII
);
926 if(errorCase
.testToUnicode
==TRUE
){
927 testAPI((src
==NULL
)? NULL
: buf
,src
,
928 IDNToUnicodeName
, errorCase
.useSTD3ASCIIRules
,
929 errorCase
.expected
, TRUE
, TRUE
, IDNToUnicode
);
936 void TestIDNA::testConformance(const char* toASCIIName, TestFunc toASCII,
937 const char* IDNToASCIIName, TestFunc IDNToASCII,
938 const char* IDNToUnicodeName, TestFunc IDNToUnicode,
939 const char* toUnicodeName, TestFunc toUnicode){
940 UChar src[MAX_DEST_SIZE];
942 UChar expected[MAX_DEST_SIZE];
943 int32_t expectedLen = 0;
944 for(int32_t i=0;i< (int32_t)(sizeof(conformanceTestCases)/sizeof(conformanceTestCases[0]));i++){
945 const char* utf8Chars1 = conformanceTestCases[i].in;
946 int32_t utf8Chars1Len = (int32_t)strlen(utf8Chars1);
947 const char* utf8Chars2 = conformanceTestCases[i].out;
948 int32_t utf8Chars2Len = (utf8Chars2 == NULL) ? 0 : (int32_t)strlen(utf8Chars2);
950 UErrorCode status = U_ZERO_ERROR;
951 u_strFromUTF8(src,MAX_DEST_SIZE,&srcLen,utf8Chars1,utf8Chars1Len,&status);
952 if(U_FAILURE(status)){
953 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
956 if(utf8Chars2 != NULL){
957 u_strFromUTF8(expected,MAX_DEST_SIZE,&expectedLen,utf8Chars2,utf8Chars2Len, &status);
958 if(U_FAILURE(status)){
959 errln(UnicodeString("Conversion of UTF8 source in conformanceTestCases[") + i +UnicodeString( "].in ( ")+prettify(utf8Chars1) +UnicodeString(" ) failed. Error: ")+ UnicodeString(u_errorName(status)));
964 if(conformanceTestCases[i].expectedStatus != U_ZERO_ERROR){
966 testAPI(src,expected,
967 IDNToASCIIName, FALSE,
968 conformanceTestCases[i].expectedStatus,
970 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
973 testAPI(src,expected,
975 conformanceTestCases[i].expectedStatus, TRUE,
976 (conformanceTestCases[i].expectedStatus != U_IDNA_UNASSIGNED_ERROR),
981 IDNToUnicodeName, FALSE,
982 conformanceTestCases[i].expectedStatus, TRUE, TRUE, IDNToUnicode);
984 toUnicodeName, FALSE,
985 conformanceTestCases[i].expectedStatus, TRUE, TRUE, toUnicode);
991 // test and ascertain
992 // func(func(func(src))) == func(src)
993 void TestIDNA::testChaining(const UChar
* src
,int32_t numIterations
,const char* testName
,
994 UBool useSTD3ASCIIRules
, UBool caseInsensitive
, TestFunc func
){
995 UChar even
[MAX_DEST_SIZE
];
996 UChar odd
[MAX_DEST_SIZE
];
997 UChar expected
[MAX_DEST_SIZE
];
998 int32_t i
=0,evenLen
=0,oddLen
=0,expectedLen
=0;
999 UErrorCode status
= U_ZERO_ERROR
;
1000 int32_t srcLen
= u_strlen(src
);
1001 int32_t options
= (useSTD3ASCIIRules
== TRUE
) ? UIDNA_USE_STD3_RULES
: UIDNA_DEFAULT
;
1002 UParseError parseError
;
1004 // test null-terminated source
1005 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
, options
, &parseError
, &status
);
1006 if(U_FAILURE(status
)){
1007 errln("%s null terminated source failed. Error: %s\n",testName
, u_errorName(status
));
1009 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1010 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1011 for(;i
<=numIterations
; i
++){
1013 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1014 if(U_FAILURE(status
)){
1015 errln("%s null terminated source failed\n",testName
);
1019 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1020 if(U_FAILURE(status
)){
1021 errln("%s null terminated source failed\n",testName
);
1026 if(caseInsensitive
==TRUE
){
1027 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1028 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1030 errln("Chaining for %s null terminated source failed\n",testName
);
1033 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1034 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1036 errln("Chaining for %s null terminated source failed\n",testName
);
1040 // test null-terminated source
1041 status
= U_ZERO_ERROR
;
1042 expectedLen
= func(src
,-1,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1043 if(U_FAILURE(status
)){
1044 errln("%s null terminated source with options set failed. Error: %s\n",testName
, u_errorName(status
));
1046 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1047 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1048 for(;i
<=numIterations
; i
++){
1050 evenLen
= func(odd
,-1,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1051 if(U_FAILURE(status
)){
1052 errln("%s null terminated source with options set failed\n",testName
);
1056 oddLen
= func(even
,-1,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1057 if(U_FAILURE(status
)){
1058 errln("%s null terminated source with options set failed\n",testName
);
1063 if(caseInsensitive
==TRUE
){
1064 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1065 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1067 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1070 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1071 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1073 errln("Chaining for %s null terminated source with options set failed\n",testName
);
1078 // test source with length
1079 status
= U_ZERO_ERROR
;
1080 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1081 if(U_FAILURE(status
)){
1082 errln("%s null terminated source failed. Error: %s\n",testName
, u_errorName(status
));
1084 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1085 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1086 for(;i
<=numIterations
; i
++){
1088 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1089 if(U_FAILURE(status
)){
1090 errln("%s source with source length failed\n",testName
);
1094 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
, &parseError
, &status
);
1095 if(U_FAILURE(status
)){
1096 errln("%s source with source length failed\n",testName
);
1101 if(caseInsensitive
==TRUE
){
1102 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1103 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1105 errln("Chaining for %s source with source length failed\n",testName
);
1108 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1109 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1111 errln("Chaining for %s source with source length failed\n",testName
);
1114 status
= U_ZERO_ERROR
;
1115 expectedLen
= func(src
,srcLen
,expected
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1116 if(U_FAILURE(status
)){
1117 errln("%s null terminated source with options set failed. Error: %s\n",testName
, u_errorName(status
));
1119 memcpy(odd
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1120 memcpy(even
,expected
,(expectedLen
+1) * U_SIZEOF_UCHAR
);
1121 for(;i
<=numIterations
; i
++){
1123 evenLen
= func(odd
,oddLen
,even
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1124 if(U_FAILURE(status
)){
1125 errln("%s source with source length and options set failed\n",testName
);
1129 oddLen
= func(even
,evenLen
,odd
,MAX_DEST_SIZE
,options
|UIDNA_ALLOW_UNASSIGNED
, &parseError
, &status
);
1130 if(U_FAILURE(status
)){
1131 errln("%s source with source length and options set failed\n",testName
);
1136 if(caseInsensitive
==TRUE
){
1137 if( u_strCaseCompare(even
,evenLen
, expected
,expectedLen
, 0, &status
) !=0 ||
1138 u_strCaseCompare(odd
,oddLen
, expected
,expectedLen
, 0, &status
) !=0 ){
1140 errln("Chaining for %s source with source length and options set failed\n",testName
);
1143 if( u_strncmp(even
,expected
,expectedLen
) != 0 ||
1144 u_strncmp(odd
,expected
,expectedLen
) !=0 ){
1146 errln("Chaining for %s source with source length and options set failed\n",testName
);
1150 void TestIDNA::testChaining(const char* toASCIIName
, TestFunc toASCII
,
1151 const char* toUnicodeName
, TestFunc toUnicode
){
1153 UChar buf
[MAX_DEST_SIZE
];
1155 for(i
=0;i
< (int32_t)(sizeof(asciiIn
)/sizeof(asciiIn
[0])); i
++){
1156 u_charsToUChars(asciiIn
[i
],buf
, (int32_t)(strlen(asciiIn
[i
])+1));
1157 testChaining(buf
,5,toUnicodeName
, FALSE
, FALSE
, toUnicode
);
1159 for(i
=0;i
< (int32_t)(sizeof(unicodeIn
)/sizeof(unicodeIn
[0])); i
++){
1160 testChaining(unicodeIn
[i
], 5,toASCIIName
, FALSE
, TRUE
, toASCII
);
1165 void TestIDNA::testRootLabelSeparator(const char* testName
, CompareFunc func
,
1166 const char* IDNToASCIIName
, TestFunc IDNToASCII
,
1167 const char* IDNToUnicodeName
, TestFunc IDNToUnicode
){
1171 UChar www
[] = {0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1172 UChar com
[] = {0x002E, 0x0043, 0x004F, 0x004D, 0x002E, /* root label separator */0x0000};
1173 UChar buf
[MAX_DEST_SIZE
]={0x0057, 0x0057, 0x0057, 0x002E, 0x0000};
1175 UnicodeString
source(www
), uni0(www
),uni1(www
), ascii0(www
), ascii1(www
);
1177 uni0
.append(unicodeIn
[0]);
1179 uni0
.append((UChar
)0x0000);
1181 uni1
.append(unicodeIn
[1]);
1183 uni1
.append((UChar
)0x0000);
1185 ascii0
.append(asciiIn
[0]);
1187 ascii0
.append((UChar
)0x0000);
1189 ascii1
.append(asciiIn
[1]);
1191 ascii1
.append((UChar
)0x0000);
1193 for(i
=0;i
< (int32_t)(sizeof(unicodeIn
)/sizeof(unicodeIn
[0])); i
++){
1195 u_charsToUChars(asciiIn
[i
],buf
+4, (int32_t)(strlen(asciiIn
[i
])+1));
1198 // for every entry in unicodeIn array
1199 // prepend www. and append .com
1201 source
.append(unicodeIn
[i
]);
1203 source
.append((UChar
)0x0000);
1205 const UChar
* src
= source
.getBuffer();
1206 int32_t srcLen
= u_strlen(src
); //subtract null
1208 // b) compare it with asciiIn equivalent
1209 testCompare(src
,srcLen
,buf
,u_strlen(buf
),testName
, func
,TRUE
);
1211 // a) compare it with itself
1212 testCompare(src
,srcLen
,src
,srcLen
,testName
, func
,TRUE
);
1215 // IDNToASCII comparison
1216 testAPI(src
,buf
,IDNToASCIIName
,FALSE
,U_ZERO_ERROR
,TRUE
, TRUE
, IDNToASCII
);
1217 // IDNToUnicode comparison
1218 testAPI(buf
,src
,IDNToUnicodeName
, FALSE
,U_ZERO_ERROR
, TRUE
, TRUE
, IDNToUnicode
);
1220 // c) compare it with unicodeIn not equivalent
1222 testCompare(src
,srcLen
,uni1
.getBuffer(),uni1
.length()-1,testName
, func
,FALSE
);
1224 testCompare(src
,srcLen
,uni0
.getBuffer(),uni0
.length()-1,testName
, func
,FALSE
);
1226 // d) compare it with asciiIn not equivalent
1228 testCompare(src
,srcLen
,ascii1
.getBuffer(),ascii1
.length()-1,testName
, func
,FALSE
);
1230 testCompare(src
,srcLen
,ascii0
.getBuffer(),ascii0
.length()-1,testName
, func
,FALSE
);
1235 //---------------------------------------------
1237 //---------------------------------------------
1239 void TestIDNA::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char* par
)
1241 if (exec
) logln((UnicodeString
)"TestSuite IDNA API ");
1244 case 0: name
= "TestToASCII"; if (exec
) TestToASCII(); break;
1245 case 1: name
= "TestToUnicode"; if (exec
) TestToUnicode(); break;
1246 case 2: name
= "TestIDNToASCII"; if (exec
) TestIDNToASCII(); break;
1247 case 3: name
= "TestIDNToUnicode"; if (exec
) TestIDNToUnicode(); break;
1248 case 4: name
= "TestCompare"; if (exec
) TestCompare(); break;
1249 case 5: name
= "TestErrorCases"; if (exec
) TestErrorCases(); break;
1250 case 6: name
= "TestChaining"; if (exec
) TestChaining(); break;
1251 case 7: name
= "TestRootLabelSeparator"; if(exec
) TestRootLabelSeparator(); break;
1252 case 8: name
= "TestCompareReferenceImpl"; if(exec
) TestCompareReferenceImpl(); break;
1253 case 9: name
= "TestDataFile"; if(exec
) TestDataFile(); break;
1254 case 10: name
= "TestRefIDNA"; if(exec
) TestRefIDNA(); break;
1255 case 11: name
= "TestIDNAMonkeyTest"; if(exec
) TestIDNAMonkeyTest(); break;
1258 name
= "TestConformanceTestVectors";
1260 logln("TestSuite IDNA conf----"); logln();
1262 callTest(test
, par
);
1266 default: name
= ""; break; /*needed to end loop*/
1269 void TestIDNA::TestToASCII(){
1270 testToASCII("uidna_toASCII", uidna_toASCII
);
1272 void TestIDNA::TestToUnicode(){
1273 testToUnicode("uidna_toUnicode", uidna_toUnicode
);
1275 void TestIDNA::TestIDNToASCII(){
1276 testIDNToASCII("uidna_IDNToASCII", uidna_IDNToASCII
);
1278 void TestIDNA::TestIDNToUnicode(){
1279 testIDNToUnicode("uidna_IDNToUnicode", uidna_IDNToUnicode
);
1281 void TestIDNA::TestCompare(){
1282 testCompare("uidna_compare",uidna_compare
);
1284 void TestIDNA::TestErrorCases(){
1285 testErrorCases( "uidna_IDNToASCII",uidna_IDNToASCII
,
1286 "uidna_IDNToUnicode",uidna_IDNToUnicode
);
1288 void TestIDNA::TestRootLabelSeparator(){
1289 testRootLabelSeparator( "uidna_compare",uidna_compare
,
1290 "uidna_IDNToASCII", uidna_IDNToASCII
,
1291 "uidna_IDNToUnicode",uidna_IDNToUnicode
1294 void TestIDNA::TestChaining(){
1295 testChaining("uidna_toASCII",uidna_toASCII
, "uidna_toUnicode", uidna_toUnicode
);
1299 static const int loopCount
= 100;
1300 static const int maxCharCount
= 20;
1301 static const int maxCodePoint
= 0x10ffff;
1305 static UBool initialized
= FALSE
;
1308 srand((unsigned)time(NULL
));
1311 // Assume rand has at least 12 bits of precision
1313 for (uint32_t i
=0; i
<sizeof(l
); ++i
)
1314 ((char*)&l
)[i
] = (char)((rand() & 0x0FF0) >> 4);
1319 * Return a random integer i where 0 <= i < n.
1320 * A special function that gets random codepoints from planes 0,1,2 and 14
1322 static int32_t rand_uni()
1324 int32_t retVal
= (int32_t)(randul()& 0x3FFFF);
1325 if(retVal
>= 0x30000){
1331 static int32_t randi(int32_t n
){
1332 return (int32_t) (randul() % (n
+1));
1335 void getTestSource(UnicodeString
& fillIn
) {
1337 int32_t charCount
= (randi(maxCharCount
) + 1);
1338 while (i
<charCount
) {
1339 int32_t codepoint
= rand_uni();
1340 if(codepoint
== 0x0000){
1343 fillIn
.append((UChar32
)codepoint
);
1349 UnicodeString
TestIDNA::testCompareReferenceImpl(UnicodeString
& src
,
1350 TestFunc refIDNA
, const char* refIDNAName
,
1351 TestFunc uIDNA
, const char* uIDNAName
,
1354 const UChar
* srcUChars
= src
.getBuffer();
1355 UChar exp
[MAX_DEST_SIZE
]={0};
1356 int32_t expCap
= MAX_DEST_SIZE
, expLen
=0;
1357 UErrorCode expStatus
= U_ZERO_ERROR
;
1358 UParseError parseError
;
1360 logln("Comparing "+ UnicodeString(refIDNAName
)
1361 + " with "+ UnicodeString(uIDNAName
)
1362 +" for input: " + prettify(srcUChars
));
1364 expLen
= refIDNA(srcUChars
, src
.length()-1, exp
, expCap
,
1365 options
, &parseError
, &expStatus
);
1367 UChar got
[MAX_DEST_SIZE
]={0};
1368 int32_t gotCap
= MAX_DEST_SIZE
, gotLen
=0;
1369 UErrorCode gotStatus
= U_ZERO_ERROR
;
1371 gotLen
= uIDNA(srcUChars
, src
.length()-1, got
, gotCap
,
1372 options
, &parseError
, &gotStatus
);
1374 if(expStatus
!= gotStatus
){
1375 errln("Did not get the expected status while comparing " + UnicodeString(refIDNAName
)
1376 + " with " + UnicodeString(uIDNAName
)
1377 + " Expected: " + UnicodeString(u_errorName(expStatus
))
1378 + " Got: " + UnicodeString(u_errorName(gotStatus
))
1379 + " for Source: "+ prettify(srcUChars
)
1380 + " Options: " + options
);
1381 return UnicodeString("");
1384 // now we know that both implementations yielded same error
1385 if(U_SUCCESS(expStatus
)){
1386 // compare the outputs if status == U_ZERO_ERROR
1387 if(u_strCompare(exp
, expLen
, got
, gotLen
, TRUE
) != 0){
1388 errln("Did not get the expected output while comparing " + UnicodeString(refIDNAName
)
1389 + " with " + UnicodeString(uIDNAName
)
1390 + " Expected: " + prettify(UnicodeString(exp
, expLen
))
1391 + " Got: " + prettify(UnicodeString(got
, gotLen
))
1392 + " for Source: "+ prettify(srcUChars
)
1393 + " Options: " + options
);
1395 return UnicodeString(exp
, expLen
);
1398 logln("Got the same error while comparing "
1399 + UnicodeString(refIDNAName
)
1400 + " with "+ UnicodeString(uIDNAName
)
1401 +" for input: " + prettify(srcUChars
));
1403 return UnicodeString("");
1406 void TestIDNA::testCompareReferenceImpl(const UChar
* src
, int32_t srcLen
){
1407 UnicodeString
label(src
,srcLen
);
1408 label
.append((UChar
)0x0000);
1410 //test idnaref_toASCII and idnare
1411 UnicodeString asciiLabel
= testCompareReferenceImpl(label
,
1412 idnaref_toASCII
, "idnaref_toASCII",
1413 uidna_toASCII
, "uidna_toASCII",
1414 UIDNA_ALLOW_UNASSIGNED
);
1415 testCompareReferenceImpl(label
,
1416 idnaref_toASCII
, "idnaref_toASCII",
1417 uidna_toASCII
, "uidna_toASCII",
1419 testCompareReferenceImpl(label
,
1420 idnaref_toASCII
, "idnaref_toASCII",
1421 uidna_toASCII
, "uidna_toASCII",
1422 UIDNA_USE_STD3_RULES
);
1423 testCompareReferenceImpl(label
,
1424 idnaref_toASCII
, "idnaref_toASCII",
1425 uidna_toASCII
, "uidna_toASCII",
1426 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1428 if(asciiLabel
.length()!=0){
1429 asciiLabel
.append((UChar
)0x0000);
1432 testCompareReferenceImpl(asciiLabel
,
1433 idnaref_toUnicode
, "idnaref_toUnicode",
1434 uidna_toUnicode
, "uidna_toUnicode",
1435 UIDNA_ALLOW_UNASSIGNED
);
1436 testCompareReferenceImpl(asciiLabel
,
1437 idnaref_toUnicode
, "idnaref_toUnicode",
1438 uidna_toUnicode
, "uidna_toUnicode",
1440 testCompareReferenceImpl(asciiLabel
,
1441 idnaref_toUnicode
, "idnaref_toUnicode",
1442 uidna_toUnicode
, "uidna_toUnicode",
1443 UIDNA_USE_STD3_RULES
);
1444 testCompareReferenceImpl(asciiLabel
,
1445 idnaref_toUnicode
, "idnaref_toUnicode",
1446 uidna_toUnicode
, "uidna_toUnicode",
1447 UIDNA_USE_STD3_RULES
| UIDNA_ALLOW_UNASSIGNED
);
1451 const char* failures
[] ={
1452 "\\uAA42\\U0001F8DD\\U00019D01\\U000149A3\\uD385\\U000EE0F5\\U00018B92\\U000179D1\\U00018624\\U0002227F\\U000E83C0\\U000E8DCD\\u5460\\U00017F34\\U0001570B\\u43D1\\U0002C9C9\\U000281EC\\u2105\\U000180AE\\uC5D4",
1453 "\\U0002F5A6\\uD638\\u0D0A\\u9E9C\\uFE5B\\U0001FCCB\\u66C4",
1456 void TestIDNA::TestIDNAMonkeyTest(){
1457 UnicodeString source
;
1458 UErrorCode status
= U_ZERO_ERROR
;
1461 getInstance(status
); // Init prep
1462 if (U_FAILURE(status
)) {
1463 if (status
== U_FILE_ACCESS_ERROR
) {
1464 dataerrln("[DATA] Test could not initialize.");
1466 errln("Test could not initialize. Got %s", u_errorName(status
));
1471 for(i
=0; i
<loopCount
; i
++){
1473 getTestSource(source
);
1474 source
.append((UChar
)0x0000);
1475 const UChar
* src
= source
.getBuffer();
1476 testCompareReferenceImpl(src
,source
.length()-1);
1477 testCompareReferenceImpl(src
,source
.length()-1);
1481 for (i
=0; i
<(int)(sizeof(failures
)/sizeof(failures
[0])); i
++){
1483 source
.append( UnicodeString(failures
[i
], -1, US_INV
) );
1484 source
= source
.unescape();
1485 source
.append((UChar
)0x0000);
1486 const UChar
*src
= source
.getBuffer();
1487 testCompareReferenceImpl(src
,source
.length()-1);
1488 //debug(source.getBuffer(),source.length(),UIDNA_ALLOW_UNASSIGNED);
1493 source
.append(UNICODE_STRING_SIMPLE("\\uCF18\\U00021161\\U000EEF11\\U0002BB82\\U0001D63C"));
1494 debug(source
.getBuffer(),source
.length(),UIDNA_ALLOW_UNASSIGNED
);
1496 { // test deletion of code points
1497 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
);
1498 source
= source
.unescape();
1499 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
);
1500 expected
= expected
.unescape();
1501 UnicodeString
ascii("xn--b1abfaaepdrnnbgefbadotcwatmq2g4l");
1502 ascii
.append((UChar
)0x0000);
1503 testAPI(source
.getBuffer(),ascii
.getBuffer(), "uidna_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, uidna_toASCII
);
1505 testAPI(source
.getBuffer(),ascii
.getBuffer(), "idnaref_toASCII", FALSE
, U_ZERO_ERROR
, TRUE
, TRUE
, idnaref_toASCII
);
1507 testCompareReferenceImpl(source
.getBuffer(), source
.length()-1);
1512 void TestIDNA::TestCompareReferenceImpl(){
1514 UChar src
[2] = {0,0};
1518 for(int32_t i
= 0x40000 ; i
< 0x10ffff; i
++){
1519 if(quick
==TRUE
&& i
> 0x1FFFF){
1522 if(i
>= 0x30000 && i
<= 0xF0000){
1526 src
[0] = U16_LEAD(i
);
1527 src
[1] = U16_TRAIL(i
);
1534 testCompareReferenceImpl(src
, srcLen
);
1538 void TestIDNA::TestRefIDNA(){
1539 UErrorCode status
= U_ZERO_ERROR
;
1540 getInstance(status
); // Init prep
1541 if (U_FAILURE(status
)) {
1542 if (status
== U_FILE_ACCESS_ERROR
) {
1543 dataerrln("[DATA] Test could not initialize.");
1545 errln("Test could not initialize. Got %s", u_errorName(status
));
1550 testToASCII("idnaref_toASCII", idnaref_toASCII
);
1551 testToUnicode("idnaref_toUnicode", idnaref_toUnicode
);
1552 testIDNToASCII("idnaref_IDNToASCII", idnaref_IDNToASCII
);
1553 testIDNToUnicode("idnaref_IDNToUnicode", idnaref_IDNToUnicode
);
1554 testCompare("idnaref_compare",idnaref_compare
);
1555 testErrorCases( "idnaref_IDNToASCII",idnaref_IDNToASCII
,
1556 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
);
1557 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1559 testRootLabelSeparator( "idnaref_compare",idnaref_compare
,
1560 "idnaref_IDNToASCII", idnaref_IDNToASCII
,
1561 "idnaref_IDNToUnicode",idnaref_IDNToUnicode
1563 testChaining("idnaref_toASCII",idnaref_toASCII
, "idnaref_toUnicode", idnaref_toUnicode
);
1567 void TestIDNA::TestDataFile(){
1570 TestIDNA::~TestIDNA(){
1577 NamePrepTransform
* TestIDNA::gPrep
= NULL
;
1579 NamePrepTransform
* TestIDNA::getInstance(UErrorCode
& status
){
1580 if(TestIDNA::gPrep
== NULL
){
1581 UParseError parseError
;
1582 TestIDNA::gPrep
= NamePrepTransform::createInstance(parseError
, status
);
1583 if(TestIDNA::gPrep
==NULL
){
1584 //status = U_MEMORY_ALLOCATION_ERROR;
1588 return TestIDNA::gPrep
;
1591 #endif /* #if !UCONFIG_NO_IDNA */