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