*** empty log message ***
[libidn.git] / tst_punycode.c
blobd56b524f66e498e756b3c57ebbed6de528f9fa4c
1 /* tst_punycode.c Self tests for punycode.
2 * Copyright (C) 2002 Simon Josefsson
4 * This file is part of Libstringprep.
6 * Libstringprep is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Libstringprep is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Libstringprep; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "internal.h"
24 static int debug = 0;
25 static int error_count = 0;
26 static int break_on_error = 0;
28 static void
29 fail (const char *format, ...)
31 va_list arg_ptr;
33 va_start (arg_ptr, format);
34 vfprintf (stderr, format, arg_ptr);
35 va_end (arg_ptr);
36 error_count++;
37 if (break_on_error)
38 exit (1);
41 static void
42 ucs4print (unsigned long *str, ssize_t len)
44 int i;
46 printf ("\t;; ");
47 for (i = 0; len >= 0 ? i < len : str[i]; i++)
49 printf ("U+%04lux ", str[i]);
50 if ((i + 1) % 4 == 0)
51 printf (" ");
52 if ((i + 1) % 8 == 0 && i + 1 < len)
53 printf ("\n\t;; ");
55 puts ("");
58 struct punycode
60 char *name;
61 size_t inlen;
62 unsigned long in[100];
63 char *out;
64 int rc;
66 punycode[] =
69 "(A) Arabic (Egyptian)", 17,
71 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643,
72 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A,
73 0x061F}
74 , "egbpdaj6bu4bxfgehfvwxn", PUNYCODE_SUCCESS}
77 "(B) Chinese (simplified)", 9,
79 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 0x6587}
80 , "ihqwcrb4cv8a8dqg056pqjye", PUNYCODE_SUCCESS}
83 "(C) Chinese (traditional)", 9,
85 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 0x6587}
86 , "ihqwctvzc91f659drss3x8bo0yb", PUNYCODE_SUCCESS}
89 "(D) Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky", 22,
91 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073,
92 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076,
93 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079}
94 , "Proprostnemluvesky-uyb24dma41a", PUNYCODE_SUCCESS}
97 "(E) Hebrew:", 22,
99 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5,
100 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9,
101 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA}
102 , "4dbcagdahymbxekheh6e0a7fei0b", PUNYCODE_SUCCESS}
105 "(F) Hindi (Devanagari):", 30,
107 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928,
108 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902,
109 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938,
110 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902}
111 , "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", PUNYCODE_SUCCESS}
114 "(G) Japanese (kanji and hiragana):", 18,
116 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E,
117 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044,
118 0x306E, 0x304B}
119 , "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", PUNYCODE_SUCCESS}
122 "(H) Korean (Hangul syllables):", 24,
124 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4,
125 0xC774, 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C,
126 0xB2E4, 0xBA74, 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C}
127 , "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c",
128 PUNYCODE_SUCCESS}
131 "(I) Russian (Cyrillic):", 28,
133 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435,
134 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432,
135 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443,
136 0x0441, 0x0441, 0x043A, 0x0438}
137 , "b1abfaaepdrnnbgefbadotcwatmq2g4l", PUNYCODE_SUCCESS}
140 "(J) Spanish: Porqu<eacute>nopuedensimplementehablarenEspa<ntilde>ol", 40,
142 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F,
143 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069,
144 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074,
145 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065,
146 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C}
147 , "PorqunopuedensimplementehablarenEspaol-fmd56a", PUNYCODE_SUCCESS}
150 "(K) Vietnamese:", 31,
152 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD,
153 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3,
154 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069,
155 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074}
156 , "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g", PUNYCODE_SUCCESS}
159 "(L) 3<nen>B<gumi><kinpachi><sensei>", 8,
161 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F}
162 , "3B-ww4c5e180e575a65lsy2b", PUNYCODE_SUCCESS}
165 "(M) <amuro><namie>-with-SUPER-MONKEYS", 24,
167 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069,
168 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052,
169 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053}
170 , "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n", PUNYCODE_SUCCESS}
173 "(N) Hello-Another-Way-<sorezore><no><basho>", 25,
175 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E,
176 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061,
177 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834,
178 0x6240}
179 , "Hello-Another-Way--fc4qua05auwb3674vfr0b", PUNYCODE_SUCCESS}
182 "(O) <hitotsu><yane><no><shita>2", 8,
184 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032}
185 , "2-u9tlzr9756bt3uc0v", PUNYCODE_SUCCESS}
188 "(P) Maji<de>Koi<suru>5<byou><mae>", 13,
190 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069,
191 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D}
192 , "MajiKoi5-783gue6qz075azm5e", PUNYCODE_SUCCESS}
195 "(Q) <pafii>de<runba>", 9,
197 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0}
198 , "de-jg4avhby1noc0d", PUNYCODE_SUCCESS}
201 "(R) <sono><supiido><de>", 7,
203 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067}
204 , "d9juau41awczczp", PUNYCODE_SUCCESS}
207 "(S) -> $1.00 <-", 11,
209 0x002D, 0x003E, 0x0020, 0x0024, 0x0031, 0x002E, 0x0030, 0x0030,
210 0x0020, 0x003C, 0x002D}
211 , "-> $1.00 <--", PUNYCODE_SUCCESS}
215 main (int argc, char *argv[])
217 char *p;
218 unsigned long *q;
219 int rc, i;
220 size_t outlen;
223 if (strcmp (argv[argc - 1], "-v") == 0 ||
224 strcmp (argv[argc - 1], "--verbose") == 0)
225 debug = 1;
226 else if (strcmp (argv[argc - 1], "-b") == 0 ||
227 strcmp (argv[argc - 1], "--break-on-error") == 0)
228 break_on_error = 1;
229 else if (strcmp (argv[argc - 1], "-h") == 0 ||
230 strcmp (argv[argc - 1], "-?") == 0 ||
231 strcmp (argv[argc - 1], "--help") == 0)
233 printf ("Usage: %s [-vbh?] [--verbose] [--break-on-error] [--help]\n",
234 argv[0]);
235 return 1;
237 while (argc-- > 1);
239 p = malloc (sizeof(*p) * BUFSIZ);
240 if (p == NULL)
241 fail ("malloc() returned NULL\n");
243 q = malloc (sizeof(*q) * BUFSIZ);
244 if (q == NULL)
245 fail ("malloc() returned NULL\n");
247 for (i = 0; i < sizeof (punycode) / sizeof (punycode[0]); i++)
249 if (debug)
250 printf ("PUNYCODE entry %d: %s\n", i, punycode[i].name);
252 if (debug)
254 printf ("in:\n");
255 ucs4print (punycode[i].in, punycode[i].inlen);
258 outlen = BUFSIZ;
259 rc = punycode_encode (punycode[i].inlen, punycode[i].in,
260 NULL, &outlen, p);
261 if (rc != punycode[i].rc)
263 fail ("punycode_encode() entry %d failed: %d\n", i, rc);
264 if (debug)
265 printf ("FATAL\n");
266 continue;
269 if (rc == PUNYCODE_SUCCESS)
270 p[outlen] = '\0';
272 if (debug && rc == PUNYCODE_SUCCESS)
274 printf ("computed out: %s\n", p);
275 printf ("expected out: %s\n", punycode[i].out);
277 else if (debug)
278 printf ("returned %d expected %d\n", rc, punycode[i].rc);
280 if (rc == PUNYCODE_SUCCESS)
282 if (strlen (punycode[i].out) != strlen (p) ||
283 memcmp (punycode[i].out, p, strlen (p)) != 0)
285 fail ("punycode() entry %d failed\n", i);
286 if (debug)
287 printf ("ERROR\n");
289 else if (debug)
290 printf ("OK\n\n");
292 else if (debug)
293 printf ("OK\n\n");
295 if (debug)
297 printf ("in: %s\n", punycode[i].out);
300 outlen = BUFSIZ;
301 rc = punycode_decode (strlen(punycode[i].out), punycode[i].out,
302 &outlen, q, NULL);
303 if (rc != punycode[i].rc)
305 fail ("punycode() entry %d failed: %d\n", i, rc);
306 if (debug)
307 printf ("FATAL\n");
308 continue;
311 if (debug && rc == PUNYCODE_SUCCESS)
313 printf ("computed out:\n");
314 ucs4print (q, outlen);
315 printf ("expected out:\n");
316 ucs4print (punycode[i].in, punycode[i].inlen);
318 else if (debug)
319 printf ("returned %d expected %d\n", rc, punycode[i].rc);
321 if (rc == PUNYCODE_SUCCESS)
323 if (punycode[i].inlen != outlen ||
324 memcmp (punycode[i].in, q, outlen) != 0)
326 fail ("punycode_decode() entry %d failed\n", i);
327 if (debug)
328 printf ("ERROR\n");
330 else if (debug)
331 printf ("OK\n\n");
333 else if (debug)
334 printf ("OK\n\n");
337 free (q);
338 free (p);
340 if (debug)
341 printf ("Punycode self tests done with %d errors\n", error_count);
343 return error_count ? 1 : 0;