Line data Source code
1 : /* tst_punycode.c --- Self tests for punycode. 2 : * Copyright (C) 2002-2020 Simon Josefsson 3 : * 4 : * This file is part of GNU Libidn. 5 : * 6 : * This program 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 3 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program 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. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 : * 19 : */ 20 : 21 : #ifdef HAVE_CONFIG_H 22 : # include "config.h" 23 : #endif 24 : 25 : #include <stdio.h> 26 : #include <stdlib.h> 27 : #include <stdarg.h> 28 : #include <string.h> 29 : 30 : #include <punycode.h> 31 : 32 : #include "utils.h" 33 : 34 : struct punycode 35 : { 36 : const char *name; 37 : size_t inlen; 38 : uint32_t in[100]; 39 : const char *out; 40 : int rc; 41 : }; 42 : 43 : const struct punycode punycode[] = { 44 : { 45 : "(A) Arabic (Egyptian)", 17, 46 : { 47 : 0x0644, 0x064A, 0x0647, 0x0645, 0x0627, 0x0628, 0x062A, 0x0643, 48 : 0x0644, 0x0645, 0x0648, 0x0634, 0x0639, 0x0631, 0x0628, 0x064A, 49 : 0x061F}, "egbpdaj6bu4bxfgehfvwxn", PUNYCODE_SUCCESS}, 50 : { 51 : "(B) Chinese (simplified)", 9, 52 : { 53 : 0x4ED6, 0x4EEC, 0x4E3A, 0x4EC0, 0x4E48, 0x4E0D, 0x8BF4, 0x4E2D, 54 : 0x6587}, "ihqwcrb4cv8a8dqg056pqjye", PUNYCODE_SUCCESS}, 55 : { 56 : "(C) Chinese (traditional)", 9, 57 : { 58 : 0x4ED6, 0x5011, 0x7232, 0x4EC0, 0x9EBD, 0x4E0D, 0x8AAA, 0x4E2D, 59 : 0x6587}, "ihqwctvzc91f659drss3x8bo0yb", PUNYCODE_SUCCESS}, 60 : { 61 : "(D) Czech: Pro<ccaron>prost<ecaron>nemluv<iacute><ccaron>esky", 22, 62 : { 63 : 0x0050, 0x0072, 0x006F, 0x010D, 0x0070, 0x0072, 0x006F, 0x0073, 64 : 0x0074, 0x011B, 0x006E, 0x0065, 0x006D, 0x006C, 0x0075, 0x0076, 65 : 0x00ED, 0x010D, 0x0065, 0x0073, 0x006B, 0x0079}, 66 : "Proprostnemluvesky-uyb24dma41a", PUNYCODE_SUCCESS}, 67 : { 68 : "(E) Hebrew:", 22, 69 : { 70 : 0x05DC, 0x05DE, 0x05D4, 0x05D4, 0x05DD, 0x05E4, 0x05E9, 0x05D5, 71 : 0x05D8, 0x05DC, 0x05D0, 0x05DE, 0x05D3, 0x05D1, 0x05E8, 0x05D9, 72 : 0x05DD, 0x05E2, 0x05D1, 0x05E8, 0x05D9, 0x05EA}, 73 : "4dbcagdahymbxekheh6e0a7fei0b", PUNYCODE_SUCCESS}, 74 : { 75 : "(F) Hindi (Devanagari):", 30, 76 : { 77 : 0x092F, 0x0939, 0x0932, 0x094B, 0x0917, 0x0939, 0x093F, 0x0928, 78 : 0x094D, 0x0926, 0x0940, 0x0915, 0x094D, 0x092F, 0x094B, 0x0902, 79 : 0x0928, 0x0939, 0x0940, 0x0902, 0x092C, 0x094B, 0x0932, 0x0938, 80 : 0x0915, 0x0924, 0x0947, 0x0939, 0x0948, 0x0902}, 81 : "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", PUNYCODE_SUCCESS}, 82 : { 83 : "(G) Japanese (kanji and hiragana):", 18, 84 : { 85 : 0x306A, 0x305C, 0x307F, 0x3093, 0x306A, 0x65E5, 0x672C, 0x8A9E, 86 : 0x3092, 0x8A71, 0x3057, 0x3066, 0x304F, 0x308C, 0x306A, 0x3044, 87 : 0x306E, 0x304B}, 88 : "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", PUNYCODE_SUCCESS}, 89 : { 90 : "(H) Korean (Hangul syllables):", 24, 91 : { 92 : 0xC138, 0xACC4, 0xC758, 0xBAA8, 0xB4E0, 0xC0AC, 0xB78C, 0xB4E4, 93 : 0xC774, 0xD55C, 0xAD6D, 0xC5B4, 0xB97C, 0xC774, 0xD574, 0xD55C, 94 : 0xB2E4, 0xBA74, 0xC5BC, 0xB9C8, 0xB098, 0xC88B, 0xC744, 0xAE4C}, 95 : "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c", 96 : PUNYCODE_SUCCESS}, 97 : { 98 : "(I) Russian (Cyrillic):", 28, 99 : { 100 : 0x043F, 0x043E, 0x0447, 0x0435, 0x043C, 0x0443, 0x0436, 0x0435, 101 : 0x043E, 0x043D, 0x0438, 0x043D, 0x0435, 0x0433, 0x043E, 0x0432, 102 : 0x043E, 0x0440, 0x044F, 0x0442, 0x043F, 0x043E, 0x0440, 0x0443, 103 : 0x0441, 0x0441, 0x043A, 0x0438}, 104 : "b1abfaaepdrnnbgefbadotcwatmq2g4l", PUNYCODE_SUCCESS}, 105 : { 106 : "(J) Spanish: Porqu<eacute>nopuedensimplementehablarenEspa<ntilde>ol", 40, 107 : { 108 : 0x0050, 0x006F, 0x0072, 0x0071, 0x0075, 0x00E9, 0x006E, 0x006F, 109 : 0x0070, 0x0075, 0x0065, 0x0064, 0x0065, 0x006E, 0x0073, 0x0069, 110 : 0x006D, 0x0070, 0x006C, 0x0065, 0x006D, 0x0065, 0x006E, 0x0074, 111 : 0x0065, 0x0068, 0x0061, 0x0062, 0x006C, 0x0061, 0x0072, 0x0065, 112 : 0x006E, 0x0045, 0x0073, 0x0070, 0x0061, 0x00F1, 0x006F, 0x006C}, 113 : "PorqunopuedensimplementehablarenEspaol-fmd56a", PUNYCODE_SUCCESS}, 114 : { 115 : "(K) Vietnamese:", 31, 116 : { 117 : 0x0054, 0x1EA1, 0x0069, 0x0073, 0x0061, 0x006F, 0x0068, 0x1ECD, 118 : 0x006B, 0x0068, 0x00F4, 0x006E, 0x0067, 0x0074, 0x0068, 0x1EC3, 119 : 0x0063, 0x0068, 0x1EC9, 0x006E, 0x00F3, 0x0069, 0x0074, 0x0069, 120 : 0x1EBF, 0x006E, 0x0067, 0x0056, 0x0069, 0x1EC7, 0x0074}, 121 : "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g", PUNYCODE_SUCCESS}, 122 : { 123 : "(L) 3<nen>B<gumi><kinpachi><sensei>", 8, 124 : { 125 : 0x0033, 0x5E74, 0x0042, 0x7D44, 0x91D1, 0x516B, 0x5148, 0x751F}, 126 : "3B-ww4c5e180e575a65lsy2b", PUNYCODE_SUCCESS}, 127 : { 128 : "(M) <amuro><namie>-with-SUPER-MONKEYS", 24, 129 : { 130 : 0x5B89, 0x5BA4, 0x5948, 0x7F8E, 0x6075, 0x002D, 0x0077, 0x0069, 131 : 0x0074, 0x0068, 0x002D, 0x0053, 0x0055, 0x0050, 0x0045, 0x0052, 132 : 0x002D, 0x004D, 0x004F, 0x004E, 0x004B, 0x0045, 0x0059, 0x0053}, 133 : "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n", PUNYCODE_SUCCESS}, 134 : { 135 : "(N) Hello-Another-Way-<sorezore><no><basho>", 25, 136 : { 137 : 0x0048, 0x0065, 0x006C, 0x006C, 0x006F, 0x002D, 0x0041, 0x006E, 138 : 0x006F, 0x0074, 0x0068, 0x0065, 0x0072, 0x002D, 0x0057, 0x0061, 139 : 0x0079, 0x002D, 0x305D, 0x308C, 0x305E, 0x308C, 0x306E, 0x5834, 140 : 0x6240}, 141 : "Hello-Another-Way--fc4qua05auwb3674vfr0b", PUNYCODE_SUCCESS}, 142 : { 143 : "(O) <hitotsu><yane><no><shita>2", 8, 144 : { 145 : 0x3072, 0x3068, 0x3064, 0x5C4B, 0x6839, 0x306E, 0x4E0B, 0x0032}, 146 : "2-u9tlzr9756bt3uc0v", PUNYCODE_SUCCESS}, 147 : { 148 : "(P) Maji<de>Koi<suru>5<byou><mae>", 13, 149 : { 150 : 0x004D, 0x0061, 0x006A, 0x0069, 0x3067, 0x004B, 0x006F, 0x0069, 151 : 0x3059, 0x308B, 0x0035, 0x79D2, 0x524D}, 152 : "MajiKoi5-783gue6qz075azm5e", PUNYCODE_SUCCESS}, 153 : { 154 : "(Q) <pafii>de<runba>", 9, 155 : { 156 : 0x30D1, 0x30D5, 0x30A3, 0x30FC, 0x0064, 0x0065, 0x30EB, 0x30F3, 0x30D0}, 157 : "de-jg4avhby1noc0d", PUNYCODE_SUCCESS}, 158 : { 159 : "(R) <sono><supiido><de>", 7, 160 : { 161 : 0x305D, 0x306E, 0x30B9, 0x30D4, 0x30FC, 0x30C9, 0x3067}, 162 : "d9juau41awczczp", PUNYCODE_SUCCESS}, 163 : { 164 : "(S) -> 1ドル.00 <-", 11, 165 : { 166 : 0x002D, 0x003E, 0x0020, 0x0024, 0x0031, 0x002E, 0x0030, 0x0030, 167 : 0x0020, 0x003C, 0x002D}, "-> 1ドル.00 <--", PUNYCODE_SUCCESS} 168 : }; 169 : 170 : void 171 1 : doit (void) 172 : { 173 : char *p; 174 : uint32_t *q; 175 : int rc; 176 : size_t outlen; 177 : unsigned i; 178 : 179 1 : p = malloc (sizeof (*p) * BUFSIZ); 180 1 : if (p == NULL) 181 0 : fail ("malloc() returned NULL\n"); 182 : 183 1 : q = malloc (sizeof (*q) * BUFSIZ); 184 1 : if (q == NULL) 185 0 : fail ("malloc() returned NULL\n"); 186 : 187 20 : for (i = 0; i < sizeof (punycode) / sizeof (punycode[0]); i++) 188 : { 189 19 : if (debug) 190 0 : printf ("PUNYCODE entry %u: %s\n", i, punycode[i].name); 191 : 192 19 : if (debug) 193 : { 194 0 : printf ("in:\n"); 195 0 : ucs4print (punycode[i].in, punycode[i].inlen); 196 : } 197 : 198 19 : outlen = BUFSIZ; 199 19 : rc = punycode_encode (punycode[i].inlen, punycode[i].in, 200 : NULL, &outlen, p); 201 19 : if (rc != punycode[i].rc) 202 : { 203 0 : fail ("punycode_encode() entry %u failed: %d\n", i, rc); 204 0 : if (debug) 205 0 : printf ("FATAL\n"); 206 0 : continue; 207 : } 208 : 209 19 : if (rc == PUNYCODE_SUCCESS) 210 19 : p[outlen] = '0円'; 211 : 212 19 : if (debug && rc == PUNYCODE_SUCCESS) 213 : { 214 0 : printf ("computed out: %s\n", p); 215 0 : printf ("expected out: %s\n", punycode[i].out); 216 : } 217 19 : else if (debug) 218 0 : printf ("returned %d expected %d\n", rc, punycode[i].rc); 219 : 220 19 : if (rc == PUNYCODE_SUCCESS) 221 : { 222 19 : if (strlen (punycode[i].out) != strlen (p) || 223 19 : memcmp (punycode[i].out, p, strlen (p)) != 0) 224 : { 225 0 : fail ("punycode() entry %u failed\n", i); 226 0 : if (debug) 227 0 : printf ("ERROR\n"); 228 : } 229 19 : else if (debug) 230 0 : printf ("OK\n\n"); 231 : } 232 0 : else if (debug) 233 0 : printf ("OK\n\n"); 234 : 235 19 : if (debug) 236 : { 237 0 : printf ("in: %s\n", punycode[i].out); 238 : } 239 : 240 19 : outlen = BUFSIZ; 241 19 : rc = punycode_decode (strlen (punycode[i].out), punycode[i].out, 242 : &outlen, q, NULL); 243 19 : if (rc != punycode[i].rc) 244 : { 245 0 : fail ("punycode() entry %u failed: %d\n", i, rc); 246 0 : if (debug) 247 0 : printf ("FATAL\n"); 248 0 : continue; 249 : } 250 : 251 19 : if (debug && rc == PUNYCODE_SUCCESS) 252 : { 253 0 : printf ("computed out:\n"); 254 0 : ucs4print (q, outlen); 255 0 : printf ("expected out:\n"); 256 0 : ucs4print (punycode[i].in, punycode[i].inlen); 257 : } 258 19 : else if (debug) 259 0 : printf ("returned %d expected %d\n", rc, punycode[i].rc); 260 : 261 19 : if (rc == PUNYCODE_SUCCESS) 262 : { 263 19 : if (punycode[i].inlen != outlen || 264 19 : memcmp (punycode[i].in, q, outlen) != 0) 265 : { 266 0 : fail ("punycode_decode() entry %u failed\n", i); 267 0 : if (debug) 268 0 : printf ("ERROR\n"); 269 : } 270 19 : else if (debug) 271 0 : printf ("OK\n\n"); 272 : } 273 0 : else if (debug) 274 0 : printf ("OK\n\n"); 275 : } 276 : 277 1 : free (q); 278 1 : free (p); 279 1 : }