OSDN Git Service

Add MS7619SE
[uclinux-h8/uClinux-dist.git] / lib / libidn / tests / tst_stringprep.c
1 /* tst_stringprep.c     Self tests for stringprep().
2  * Copyright (C) 2002, 2003, 2004  Simon Josefsson
3  *
4  * This file is part of GNU Libidn.
5  *
6  * GNU Libidn 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.
10  *
11  * GNU Libidn 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 GNU Libidn; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <stdarg.h>
29 #include <string.h>
30
31 #include <stringprep.h>
32
33 #include "utils.h"
34
35 struct stringprep
36 {
37   const char *comment;
38   const char *in;
39   const char *out;
40   const char *profile;
41   int flags;
42   int rc;
43 };
44
45 const struct stringprep strprep[] = {
46   {"Map to nothing",
47    "foo\xC2\xAD\xCD\x8F\xE1\xA0\x86\xE1\xA0\x8B"
48    "bar" "\xE2\x80\x8B\xE2\x81\xA0" "baz\xEF\xB8\x80\xEF\xB8\x88"
49    "\xEF\xB8\x8F\xEF\xBB\xBF", "foobarbaz"},
50   {"Case folding ASCII U+0043 U+0041 U+0046 U+0045", "CAFE", "cafe"},
51   {"Case folding 8bit U+00DF (german sharp s)", "\xC3\x9F", "ss"},
52   {"Case folding U+0130 (turkish capital I with dot)",
53    "\xC4\xB0", "i\xcc\x87"},
54   {"Case folding multibyte U+0143 U+037A",
55    "\xC5\x83\xCD\xBA", "\xC5\x84 \xCE\xB9"},
56   {"Case folding U+2121 U+33C6 U+1D7BB",
57    "\xE2\x84\xA1\xE3\x8F\x86\xF0\x9D\x9E\xBB",
58    "telc\xE2\x88\x95" "kg\xCF\x83"},
59   {"Normalization of U+006a U+030c U+00A0 U+00AA",
60    "\x6A\xCC\x8C\xC2\xA0\xC2\xAA", "\xC7\xB0 a"},
61   {"Case folding U+1FB7 and normalization",
62    "\xE1\xBE\xB7", "\xE1\xBE\xB6\xCE\xB9"},
63   {"Self-reverting case folding U+01F0 and normalization",
64    "\xC7\xB0", "\xC7\xB0"},
65   {"Self-reverting case folding U+0390 and normalization",
66    "\xCE\x90", "\xCE\x90"},
67   {"Self-reverting case folding U+03B0 and normalization",
68    "\xCE\xB0", "\xCE\xB0"},
69   {"Self-reverting case folding U+1E96 and normalization",
70    "\xE1\xBA\x96", "\xE1\xBA\x96"},
71   {"Self-reverting case folding U+1F56 and normalization",
72    "\xE1\xBD\x96", "\xE1\xBD\x96"},
73   {"ASCII space character U+0020", "\x20", "\x20"},
74   {"Non-ASCII 8bit space character U+00A0", "\xC2\xA0", "\x20"},
75   {"Non-ASCII multibyte space character U+1680",
76    "\xE1\x9A\x80", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
77   {"Non-ASCII multibyte space character U+2000", "\xE2\x80\x80", "\x20"},
78   {"Zero Width Space U+200b", "\xE2\x80\x8b", ""},
79   {"Non-ASCII multibyte space character U+3000", "\xE3\x80\x80", "\x20"},
80   {"ASCII control characters U+0010 U+007F", "\x10\x7F", "\x10\x7F"},
81   {"Non-ASCII 8bit control character U+0085",
82    "\xC2\x85", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
83   {"Non-ASCII multibyte control character U+180E",
84    "\xE1\xA0\x8E", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
85   {"Zero Width No-Break Space U+FEFF", "\xEF\xBB\xBF", ""},
86   {"Non-ASCII control character U+1D175",
87    "\xF0\x9D\x85\xB5", NULL, "Nameprep", 0,
88    STRINGPREP_CONTAINS_PROHIBITED},
89   {"Plane 0 private use character U+F123",
90    "\xEF\x84\xA3", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
91   {"Plane 15 private use character U+F1234",
92    "\xF3\xB1\x88\xB4", NULL, "Nameprep", 0,
93    STRINGPREP_CONTAINS_PROHIBITED},
94   {"Plane 16 private use character U+10F234",
95    "\xF4\x8F\x88\xB4", NULL, "Nameprep", 0,
96    STRINGPREP_CONTAINS_PROHIBITED},
97   {"Non-character code point U+8FFFE",
98    "\xF2\x8F\xBF\xBE", NULL, "Nameprep", 0,
99    STRINGPREP_CONTAINS_PROHIBITED},
100   {"Non-character code point U+10FFFF",
101    "\xF4\x8F\xBF\xBF", NULL, "Nameprep", 0,
102    STRINGPREP_CONTAINS_PROHIBITED},
103   {"Surrogate code U+DF42",
104    "\xED\xBD\x82", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
105   {"Non-plain text character U+FFFD",
106    "\xEF\xBF\xBD", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
107   {"Ideographic description character U+2FF5",
108    "\xE2\xBF\xB5", NULL, "Nameprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
109   {"Display property character U+0341", "\xCD\x81", "\xCC\x81"},
110   {"Left-to-right mark U+200E",
111    "\xE2\x80\x8E", "\xCC\x81", "Nameprep", 0,
112    STRINGPREP_CONTAINS_PROHIBITED},
113   {"Deprecated U+202A", "\xE2\x80\xAA", "\xCC\x81", "Nameprep", 0,
114    STRINGPREP_CONTAINS_PROHIBITED},
115   {"Language tagging character U+E0001",
116    "\xF3\xA0\x80\x81", "\xCC\x81", "Nameprep", 0,
117    STRINGPREP_CONTAINS_PROHIBITED},
118   {"Language tagging character U+E0042",
119    "\xF3\xA0\x81\x82", NULL, "Nameprep", 0,
120    STRINGPREP_CONTAINS_PROHIBITED},
121   {"Bidi: RandALCat character U+05BE and LCat characters",
122    "foo\xD6\xBE" "bar", NULL, "Nameprep", 0,
123    STRINGPREP_BIDI_BOTH_L_AND_RAL},
124   {"Bidi: RandALCat character U+FD50 and LCat characters",
125    "foo\xEF\xB5\x90" "bar", NULL, "Nameprep", 0,
126    STRINGPREP_BIDI_BOTH_L_AND_RAL},
127   {"Bidi: RandALCat character U+FB38 and LCat characters",
128    "foo\xEF\xB9\xB6" "bar", "foo \xd9\x8e" "bar"},
129   {"Bidi: RandALCat without trailing RandALCat U+0627 U+0031",
130    "\xD8\xA7\x31", NULL, "Nameprep", 0, STRINGPREP_BIDI_LEADTRAIL_NOT_RAL},
131   {"Bidi: RandALCat character U+0627 U+0031 U+0628",
132    "\xD8\xA7\x31\xD8\xA8", "\xD8\xA7\x31\xD8\xA8"},
133   {"Unassigned code point U+E0002",
134    "\xF3\xA0\x80\x82", NULL, "Nameprep", STRINGPREP_NO_UNASSIGNED,
135    STRINGPREP_CONTAINS_UNASSIGNED},
136   {"Larger test (shrinking)",
137    "X\xC2\xAD\xC3\x9F\xC4\xB0\xE2\x84\xA1\x6a\xcc\x8c\xc2\xa0\xc2"
138    "\xaa\xce\xb0\xe2\x80\x80", "xssi\xcc\x87" "tel\xc7\xb0 a\xce\xb0 ",
139    "Nameprep"},
140   {"Larger test (expanding)",
141    "X\xC3\x9F\xe3\x8c\x96\xC4\xB0\xE2\x84\xA1\xE2\x92\x9F\xE3\x8c\x80",
142    "xss\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88"
143    "\xe3\x83\xab" "i\xcc\x87" "tel\x28" "d\x29\xe3\x82\xa2\xe3\x83\x91"
144    "\xe3\x83\xbc\xe3\x83\x88"},
145   {"Test of prohibited ASCII character U+0020",
146    "\x20", NULL, "Nodeprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
147   {"Test of NFKC U+00A0 and prohibited character U+0020",
148    "\xC2\xA0", NULL, "Nodeprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
149   {"Case map + normalization", "\xC2\xB5", "\xCE\xBC", "Nameprep"},
150   /* The rest are rather non-interesting, but no point in removing
151      working test cases... */
152   {"case_nonfkc", "\xC2\xB5", "\xCE\xBC", "Nameprep", STRINGPREP_NO_NFKC,
153    STRINGPREP_FLAG_ERROR},
154   {"NFKC test", "\xC2\xAA", "\x61", "Nameprep"},
155   {"nameprep, exposed a bug in libstringprep 0.0.5",
156    "\xC2\xAA\x0A", "\x61\x0A"},
157   {"unassigned code point U+0221", "\xC8\xA1", "\xC8\xA1", "Nameprep"},
158   {"Unassigned code point U+0221",
159    "\xC8\xA1", NULL, "Nameprep", STRINGPREP_NO_UNASSIGNED,
160    STRINGPREP_CONTAINS_UNASSIGNED},
161   {"Unassigned code point U+0236", "\xC8\xB6", "\xC8\xB6", "Nameprep"},
162   {"unassigned code point U+0236",
163    "\xC8\xB6", NULL, "Nameprep", STRINGPREP_NO_UNASSIGNED,
164    STRINGPREP_CONTAINS_UNASSIGNED},
165   {"bidi both RandALCat and LCat  U+0627 U+00AA U+0628",
166    "\xD8\xA7\xC2\xAA\xD8\xA8", NULL, "Nameprep", 0,
167    STRINGPREP_BIDI_BOTH_L_AND_RAL},
168   /* XMPP */
169   {"XMPP node profile prohibited output",
170    "foo@bar", NULL, "Nodeprep", 0, STRINGPREP_CONTAINS_PROHIBITED},
171   {"XMPP resource profile on same string should work though",
172    "foo@bar", "foo@bar", "Resourceprep"},
173   /* iSCSI */
174   {"iSCSI 1", "Example-Name", "example-name", "iSCSI"},
175   {"iSCSI 2", "O+o", NULL, "iSCSI", 0, STRINGPREP_CONTAINS_PROHIBITED},
176   {"iSCSI 3", "\x01", NULL, "iSCSI", 0, STRINGPREP_CONTAINS_PROHIBITED},
177   {"iSCSI 4", "\xE3\x80\x82", NULL, "iSCSI", 0, STRINGPREP_CONTAINS_PROHIBITED},
178   {"iSCSI 5", "\xE2\xBF\xB5", NULL, "iSCSI", 0, STRINGPREP_CONTAINS_PROHIBITED},
179   {"SASL profile", "Example\xC2\xA0" "Name", "Example Name", "SASLprep"},
180   /* SASL trace */
181   {"SASL ANONYMOUS plain mechanism", "simon@josefsson.org",
182    "simon@josefsson.org", "plain"},
183   {"SASLprep 1 old", "x\xC2\xADy", "xy", "SASLprep"},
184   {"SASLprep 4 old", "\xE2\x85\xA3", "IV", "SASLprep"},
185   /* SASLprep test vectors. */
186   {"SASLprep 1 SOFT HYPHEN mapped to nothing", "I\xC2\xADX", "IX", "SASLprep"},
187   {"SASLprep 2 no transformation", "user", "user", "SASLprep"},
188   {"SASLprep 3 case preserved, will not match #2", "USER", "USER",
189    "SASLprep"},
190   {"SASLprep 4 output is NFKC, input in ISO 8859-1", "\xC2\xAA", "a",
191    "SASLprep"},
192   {"SASLprep 5 output is NFKC, will match #1", "\xE2\x85\xA8", "IX",
193    "SASLprep"},
194   {"SASLprep 6 Error - prohibited character", "\x07", NULL, "SASLprep",
195    0, STRINGPREP_CONTAINS_PROHIBITED},
196   {"SASLprep 7 Error - bidirectional check", "\xD8\xA7" "1", NULL, "SASLprep",
197    0, STRINGPREP_BIDI_LEADTRAIL_NOT_RAL}
198 };
199
200 void
201 doit (void)
202 {
203   char *p;
204   int rc;
205   size_t i;
206
207   if (!stringprep_check_version (STRINGPREP_VERSION))
208     fail ("stringprep_check_version() failed\n");
209
210   for (i = 0; i < sizeof (strprep) / sizeof (strprep[0]); i++)
211     {
212       if (debug)
213         printf ("STRINGPREP entry %d\n", i);
214
215       if (debug)
216         {
217           printf ("flags: %d\n", strprep[i].flags);
218
219           printf ("in: ");
220           escapeprint (strprep[i].in, strlen (strprep[i].in));
221           hexprint (strprep[i].in, strlen (strprep[i].in));
222           binprint (strprep[i].in, strlen (strprep[i].in));
223         }
224
225       {
226         uint32_t *l;
227         char *x;
228         l = stringprep_utf8_to_ucs4 (strprep[i].in, -1, NULL);
229         x = stringprep_ucs4_to_utf8 (l, -1, NULL, NULL);
230         free (l);
231
232         if (strcmp (strprep[i].in, x) != 0)
233           {
234             fail ("bad UTF-8 in entry %d\n", i);
235             if (debug)
236               {
237                 puts ("expected:");
238                 escapeprint (strprep[i].in, strlen (strprep[i].in));
239                 hexprint (strprep[i].in, strlen (strprep[i].in));
240                 puts ("computed:");
241                 escapeprint (x, strlen (x));
242                 hexprint (x, strlen (x));
243               }
244           }
245
246         free (x);
247       }
248       rc = stringprep_profile (strprep[i].in, &p,
249                                strprep[i].profile ?
250                                strprep[i].profile :
251                                "Nameprep", strprep[i].flags);
252       if (rc != strprep[i].rc)
253         {
254           fail ("stringprep() entry %d failed: %d\n", i, rc);
255           if (debug)
256             printf ("FATAL\n");
257           if (rc == STRINGPREP_OK)
258             free (p);
259           continue;
260         }
261
262       if (debug && rc == STRINGPREP_OK)
263         {
264           printf ("out: ");
265           escapeprint (p, strlen (p));
266           hexprint (p, strlen (p));
267           binprint (p, strlen (p));
268
269           printf ("expected out: ");
270           escapeprint (strprep[i].out, strlen (strprep[i].out));
271           hexprint (strprep[i].out, strlen (strprep[i].out));
272           binprint (strprep[i].out, strlen (strprep[i].out));
273         }
274       else if (debug)
275         printf ("returned %d expected %d\n", rc, strprep[i].rc);
276
277       if (rc == STRINGPREP_OK)
278         {
279           if (strlen (strprep[i].out) != strlen (p) ||
280               memcmp (strprep[i].out, p, strlen (p)) != 0)
281             {
282               fail ("stringprep() entry %d failed\n", i);
283               if (debug)
284                 printf ("ERROR\n");
285             }
286           else if (debug)
287             printf ("OK\n\n");
288
289           free (p);
290         }
291       else if (debug)
292         printf ("OK\n\n");
293     }
294
295 #if 0
296   {
297     char p[20];
298     memset (p, 0, 10);
299     stringprep_unichar_to_utf8 (0x00DF, p);
300     hexprint (p, strlen (p));
301     puts ("");
302   }
303 #endif
304 }