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