aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/unit_str_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/unit_str_test.c')
-rw-r--r--src/microhttpd/unit_str_test.c786
1 files changed, 786 insertions, 0 deletions
diff --git a/src/microhttpd/unit_str_test.c b/src/microhttpd/unit_str_test.c
new file mode 100644
index 00000000..ec2cbbe6
--- /dev/null
+++ b/src/microhttpd/unit_str_test.c
@@ -0,0 +1,786 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2016 Karlson2k (Evgeny Grin)
4
5 This test tool is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2, or
8 (at your option) any later version.
9
10 This test tool is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*/
19
20/**
21 * @file microhttpd/unit_str_test.h
22 * @brief Unit tests for mhd_str functions
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include <stdio.h>
27#include <locale.h>
28#include <string.h>
29#include "mhd_options.h"
30#include <stdint.h>
31#include "mhd_limits.h"
32#include "mhd_str.h"
33#include "test_helpers.h"
34
35
36static int verbose = 0; /* verbose level (0-3)*/
37
38/* Locale names to test.
39 * Functions must not depend of current current locale,
40 * so result must be the same in any locale.
41 */
42static const char * const locale_names[] = {
43 "C",
44 "", /* System default locale */
45#if defined(_WIN32) && !defined(__CYGWIN__)
46 ".OCP", /* W32 system default OEM code page */
47 ".ACP", /* W32 system default ANSI code page */
48 ".65001", /* UTF-8 */
49 ".437",
50 ".850",
51 ".857",
52 ".866",
53 ".1250",
54 ".1251",
55 ".1252",
56 ".1254",
57 ".20866", /* number for KOI8-R */
58 ".28591", /* number for ISO-8859-1 */
59 ".28595", /* number for ISO-8859-5 */
60 ".28599", /* number for ISO-8859-9 */
61 ".28605", /* number for ISO-8859-15 */
62 "en",
63 "english",
64 "en-US",
65 "English-US",
66 "en-US.437",
67 "English_United States.437",
68 "en-US.1252",
69 "English_United States.1252",
70 "English_United States.28591",
71 "English_United States.65001",
72 "fra",
73 "french",
74 "fr-FR",
75 "French_France",
76 "fr-FR.850",
77 "french_france.850",
78 "fr-FR.1252",
79 "French_france.1252",
80 "French_france.28605",
81 "French_France.65001",
82 "de",
83 "de-DE",
84 "de-DE.850",
85 "German_Germany.850",
86 "German_Germany.1250",
87 "de-DE.1252",
88 "German_Germany.1252",
89 "German_Germany.28605",
90 "German_Germany.65001",
91 "tr",
92 "trk",
93 "turkish",
94 "tr-TR",
95 "tr-TR.1254",
96 "Turkish_Turkey.1254",
97 "tr-TR.857",
98 "Turkish_Turkey.857",
99 "Turkish_Turkey.28599",
100 "Turkish_Turkey.65001",
101 "ru",
102 "ru-RU",
103 "Russian",
104 "ru-RU.866",
105 "Russian_Russia.866",
106 "ru-RU.1251",
107 "Russian_Russia.1251",
108 "Russian_Russia.20866",
109 "Russian_Russia.28595",
110 "Russian_Russia.65001"
111#else /* ! _WIN32 || __CYGWIN__ */
112 "C.UTF-8",
113 "POSIX",
114 "en",
115 "en_US",
116 "en_US.ISO-8859-1",
117 "en_US.ISO_8859-1",
118 "en_US.ISO8859-1",
119 "en_US.iso88591",
120 "en_US.ISO-8859-15",
121 "en_US.DIS_8859-15",
122 "en_US.ISO8859-15",
123 "en_US.iso885915",
124 "en_US.1252",
125 "en_US.CP1252",
126 "en_US.UTF-8",
127 "en_US.utf8",
128 "fr",
129 "fr_FR",
130 "fr_FR.850",
131 "fr_FR.IBM850",
132 "fr_FR.1252",
133 "fr_FR.CP1252",
134 "fr_FR.ISO-8859-1",
135 "fr_FR.ISO_8859-1",
136 "fr_FR.ISO8859-1",
137 "fr_FR.iso88591",
138 "fr_FR.ISO-8859-15",
139 "fr_FR.DIS_8859-15",
140 "fr_FR.ISO8859-15",
141 "fr_FR.iso8859-15",
142 "fr_FR.UTF-8",
143 "fr_FR.utf8",
144 "de",
145 "de_DE",
146 "de_DE.850",
147 "de_DE.IBM850",
148 "de_DE.1250",
149 "de_DE.CP1250",
150 "de_DE.1252",
151 "de_DE.CP1252",
152 "de_DE.ISO-8859-1",
153 "de_DE.ISO_8859-1",
154 "de_DE.ISO8859-1",
155 "de_DE.iso88591",
156 "de_DE.ISO-8859-15",
157 "de_DE.DIS_8859-15",
158 "de_DE.ISO8859-15",
159 "de_DE.iso885915",
160 "de_DE.UTF-8",
161 "de_DE.utf8",
162 "tr",
163 "tr_TR",
164 "tr_TR.1254",
165 "tr_TR.CP1254",
166 "tr_TR.857",
167 "tr_TR.IBM857",
168 "tr_TR.ISO-8859-9",
169 "tr_TR.ISO8859-9",
170 "tr_TR.iso88599",
171 "tr_TR.UTF-8",
172 "tr_TR.utf8",
173 "ru",
174 "ru_RU",
175 "ru_RU.1251",
176 "ru_RU.CP1251",
177 "ru_RU.866",
178 "ru_RU.IBM866",
179 "ru_RU.KOI8-R",
180 "ru_RU.koi8-r",
181 "ru_RU.KOI8-RU",
182 "ru_RU.ISO-8859-5",
183 "ru_RU.ISO_8859-5",
184 "ru_RU.ISO8859-5",
185 "ru_RU.iso88595",
186 "ru_RU.UTF-8"
187#endif /* ! _WIN32 || __CYGWIN__ */
188};
189
190static const unsigned int locale_name_count = sizeof(locale_names) / sizeof(locale_names[0]);
191
192
193/*
194 * Helper functions
195 */
196
197int set_test_locale(unsigned int num)
198{
199 if (num >= locale_name_count)
200 return -1;
201 if (verbose > 2)
202 printf("Setting locale \"%s\":", locale_names[num]);
203 if (setlocale(LC_ALL, locale_names[num]))
204 {
205 if (verbose > 2)
206 printf(" succeed.\n");
207 return 1;
208 }
209 if (verbose > 2)
210 printf(" failed.\n");
211 return 0;
212}
213
214const char * get_current_locale_str(void)
215{
216 char const * loc_str = setlocale(LC_ALL, NULL);
217 return loc_str ? loc_str : "unknown";
218}
219
220static char tmp_bufs[4][4*1024]; /* should be enough for testing */
221static size_t buf_idx = 0;
222
223/* print non-printable chars as char codes */
224char * n_prnt(const char * str)
225{
226 static char * buf; /* should be enough for testing */
227 static const size_t buf_size = sizeof(tmp_bufs[0]);
228 const unsigned char * p = (const unsigned char*)str;
229 size_t w_pos = 0;
230 if (++buf_idx > 3)
231 buf_idx = 0;
232 buf = tmp_bufs[buf_idx];
233
234 while(*p && w_pos + 1 < buf_size)
235 {
236 const unsigned char c = *p;
237 if (c == '\\' || c == '"')
238 {
239 if (w_pos + 2 >= buf_size)
240 break;
241 buf[w_pos++] = '\\';
242 buf[w_pos++] = c;
243 }
244 else if (c >= 0x20 && c <= 0x7E)
245 buf[w_pos++] = c;
246 else
247 {
248 if (w_pos + 4 >= buf_size)
249 break;
250 if (snprintf(buf + w_pos, buf_size - w_pos, "\\x%02hX", (short unsigned int)c) != 4)
251 break;
252 w_pos += 4;
253 }
254 p++;
255 }
256 if (*p)
257 { /* not full string is printed */
258 /* enough space for "..." ? */
259 if (w_pos + 3 > buf_size)
260 w_pos = buf_size - 4;
261 buf[w_pos++] = '.';
262 buf[w_pos++] = '.';
263 buf[w_pos++] = '.';
264 }
265 buf[w_pos] = 0;
266 return buf;
267}
268
269
270struct str_with_len
271{
272 const char * const str;
273 const size_t len;
274};
275
276#define D_STR_W_LEN(s) {(s), (sizeof((s)) / sizeof(char)) - 1}
277
278/*
279 * String caseless equality functions tests
280 */
281
282struct two_eq_strs
283{
284 const struct str_with_len s1;
285 const struct str_with_len s2;
286};
287
288static const struct two_eq_strs eq_strings[] = {
289 {D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`.")},
290 {D_STR_W_LEN("Simple string."), D_STR_W_LEN("Simple string.")},
291 {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("SIMPLE STRING.")},
292 {D_STR_W_LEN("simple string."), D_STR_W_LEN("simple string.")},
293 {D_STR_W_LEN("simple string."), D_STR_W_LEN("Simple String.")},
294 {D_STR_W_LEN("sImPlE StRiNg."), D_STR_W_LEN("SiMpLe sTrInG.")},
295 {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("simple string.")},
296 {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz")},
297 {D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
298 {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ")},
299 {D_STR_W_LEN("zyxwvutsrqponMLKJIHGFEDCBA"), D_STR_W_LEN("ZYXWVUTSRQPONmlkjihgfedcba")},
300
301 {D_STR_W_LEN("Cha\x8cne pour le test."),
302 D_STR_W_LEN("Cha\x8cne pour le test.")}, /* "Chaîne pour le test." in CP850 */
303 {D_STR_W_LEN("cha\x8cne pOur Le TEst."),
304 D_STR_W_LEN("Cha\x8cne poUr Le teST.")},
305 {D_STR_W_LEN("Cha\xeene pour le test."),
306 D_STR_W_LEN("Cha\xeene pour le test.")}, /* "Chaîne pour le test." in CP1252/ISO-8859-1/ISO-8859-15 */
307 {D_STR_W_LEN("CHa\xeene POUR le test."),
308 D_STR_W_LEN("Cha\xeeNe pour lE TEST.")},
309 {D_STR_W_LEN("Cha\xc3\xaene pour le Test."),
310 D_STR_W_LEN("Cha\xc3\xaene pour le Test.")}, /* "Chaîne pour le test." in UTF-8 */
311 {D_STR_W_LEN("ChA\xc3\xaene pouR lE TesT."),
312 D_STR_W_LEN("Cha\xc3\xaeNe Pour le teSt.")},
313
314 {D_STR_W_LEN(".Beispiel Zeichenfolge"),
315 D_STR_W_LEN(".Beispiel Zeichenfolge")},
316 {D_STR_W_LEN(".bEisPiel ZEIchenfoLgE"),
317 D_STR_W_LEN(".BEiSpiEl zeIcheNfolge")},
318
319 {D_STR_W_LEN("Do\xa7rulama \x87izgi!"),
320 D_STR_W_LEN("Do\xa7rulama \x87izgi!")}, /* "Doğrulama çizgi!" in CP857 */
321 {D_STR_W_LEN("Do\xa7rulama \x87IzgI!"), /* Spelling intentionally incorrect here */
322 D_STR_W_LEN("Do\xa7rulama \x87izgi!")}, /* Note: 'i' is not caseless equal to 'I' in Turkish */
323 {D_STR_W_LEN("Do\xf0rulama \xe7izgi!"),
324 D_STR_W_LEN("Do\xf0rulama \xe7izgi!")}, /* "Doğrulama çizgi!" in CP1254/ISO-8859-9 */
325 {D_STR_W_LEN("Do\xf0rulamA \xe7Izgi!"),
326 D_STR_W_LEN("do\xf0rulama \xe7izgi!")},
327 {D_STR_W_LEN("Do\xc4\x9frulama \xc3\xa7izgi!"),
328 D_STR_W_LEN("Do\xc4\x9frulama \xc3\xa7izgi!")}, /* "Doğrulama çizgi!" in UTF-8 */
329 {D_STR_W_LEN("do\xc4\x9fruLAMA \xc3\xa7Izgi!"), /* Spelling intentionally incorrect here */
330 D_STR_W_LEN("DO\xc4\x9frulama \xc3\xa7izgI!")}, /* Spelling intentionally incorrect here */
331
332 {D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."),
333 D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0.")}, /* "Тестовая Строка." in CP866 */
334 {D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."),
335 D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0.")}, /* "Тестовая Строка." in CP1251 */
336 {D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."),
337 D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1.")}, /* "Тестовая Строка." in KOI8-R */
338 {D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."),
339 D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0.")}, /* "Тестовая Строка." in ISO-8859-5 */
340 {D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
341 "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."),
342 D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
343 "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0.")}, /* "Тестовая Строка." in UTF-8 */
344
345 {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
346 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
347 "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
348 "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
349 "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
350 "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
351 "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
352 "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
353 "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
354 D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
355 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@[\\]"
356 "^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
357 "\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4"
358 "\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8"
359 "\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc"
360 "\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
361 "\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4"
362 "\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")}, /* Full sequence without a-z */
363 {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
364 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
365 "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
366 "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
367 "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
368 "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
369 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
370 "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
371 "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
372 "\xfc\xfd\xfe\xff"),
373 D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
374 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
375 "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83"
376 "\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97"
377 "\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab"
378 "\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
379 "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3"
380 "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7"
381 "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb"
382 "\xfc\xfd\xfe\xff")}, /* Full sequence */
383 {D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
384 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@AB"
385 "CDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
386 "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
387 "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
388 "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
389 "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
390 "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
391 "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"),
392 D_STR_W_LEN("\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14"
393 "\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ab"
394 "cdefghijklmnopqrstuvwxyz[\\]^_`{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89"
395 "\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d"
396 "\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1"
397 "\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5"
398 "\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9"
399 "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed"
400 "\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")} /* Full with A/a match */
401};
402
403struct two_neq_strs
404{
405 const struct str_with_len s1;
406 const struct str_with_len s2;
407 const size_t dif_pos;
408};
409
410static const struct two_neq_strs neq_strings[] = {
411 {D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`"), 27},
412 {D_STR_W_LEN(".1234567890!@~%&$@#{}[]\\/!?`."), D_STR_W_LEN("1234567890!@~%&$@#{}[]\\/!?`"), 0},
413 {D_STR_W_LEN("Simple string."), D_STR_W_LEN("Simple ctring."), 7},
414 {D_STR_W_LEN("simple string."), D_STR_W_LEN("simple string"), 13},
415 {D_STR_W_LEN("simple strings"), D_STR_W_LEN("Simple String."), 13},
416 {D_STR_W_LEN("sImPlE StRiNg."), D_STR_W_LEN("SYMpLe sTrInG."), 1},
417 {D_STR_W_LEN("SIMPLE STRING."), D_STR_W_LEN("simple string.2"), 14},
418 {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz,"), D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz."), 26},
419 {D_STR_W_LEN("abcdefghijklmnopqrstuvwxyz!"), D_STR_W_LEN("ABCDEFGHIJKLMNOPQRSTUVWXYZ?"), 26},
420 {D_STR_W_LEN("zyxwvutsrqponwMLKJIHGFEDCBA"), D_STR_W_LEN("ZYXWVUTSRQPON%mlkjihgfedcba"), 13},
421
422 {D_STR_W_LEN("S\xbdur veulent plus d'\xbdufs."), /* "Sœur veulent plus d'œufs." in ISO-8859-15 */
423 D_STR_W_LEN("S\xbcUR VEULENT PLUS D'\xbcUFS."), 1},/* "SŒUR VEULENT PLUS D'ŒUFS." in ISO-8859-15 */
424 {D_STR_W_LEN("S\x9cur veulent plus d'\x9cufs."), /* "Sœur veulent plus d'œufs." in CP1252 */
425 D_STR_W_LEN("S\x8cUR VEULENT PLUS D'\x8cUFS."), 1},/* "SŒUR VEULENT PLUS D'ŒUFS." in CP1252 */
426 {D_STR_W_LEN("S\xc5\x93ur veulent plus d'\xc5\x93ufs."), /* "Sœur veulent plus d'œufs." in UTF-8 */
427 D_STR_W_LEN("S\xc5\x92UR VEULENT PLUS D'\xc5\x92UFS."), 2},/* "SŒUR VEULENT PLUS D'ŒUFS." in UTF-8 */
428
429 {D_STR_W_LEN("Um ein sch\x94nes M\x84" "dchen zu k\x81ssen."), /* "Um ein schönes Mädchen zu küssen." in CP850 */
430 D_STR_W_LEN("UM EIN SCH\x99NES M\x8e" "DCHEN ZU K\x9aSSEN."), 10},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in CP850 */
431 {D_STR_W_LEN("Um ein sch\xf6nes M\xe4" "dchen zu k\xfcssen."), /* "Um ein schönes Mädchen zu küssen." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
432 D_STR_W_LEN("UM EIN SCH\xd6NES M\xc4" "DCHEN ZU K\xdcSSEN."), 10},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in ISO-8859-1/ISO-8859-15/CP1250/CP1252 */
433 {D_STR_W_LEN("Um ein sch\xc3\xb6nes M\xc3\xa4" "dchen zu k\xc3\xbcssen."), /* "Um ein schönes Mädchen zu küssen." in UTF-8 */
434 D_STR_W_LEN("UM EIN SCH\xc3\x96NES M\xc3\x84" "DCHEN ZU K\xc3\x9cSSEN."), 11},/* "UM EIN SCHÖNES MÄDCHEN ZU KÜSSEN." in UTF-8 */
435
436 {D_STR_W_LEN("\x98stanbul"), /* "İstanbul" in CP857 */
437 D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in CP857 */
438 {D_STR_W_LEN("\xddstanbul"), /* "İstanbul" in ISO-8859-9/CP1254 */
439 D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in ISO-8859-9/CP1254 */
440 {D_STR_W_LEN("\xc4\xb0stanbul"), /* "İstanbul" in UTF-8 */
441 D_STR_W_LEN("istanbul"), 0}, /* "istanbul" in UTF-8 */
442 {D_STR_W_LEN("Diyarbak\x8dr"), /* "Diyarbakır" in CP857 */
443 D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in CP857 */
444 {D_STR_W_LEN("Diyarbak\xfdr"), /* "Diyarbakır" in ISO-8859-9/CP1254 */
445 D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in ISO-8859-9/CP1254 */
446 {D_STR_W_LEN("Diyarbak\xc4\xb1r"), /* "Diyarbakır" in UTF-8 */
447 D_STR_W_LEN("DiyarbakIR"), 8}, /* "DiyarbakIR" in UTF-8 */
448
449 {D_STR_W_LEN("\x92\xa5\xe1\xe2\xae\xa2\xa0\xef \x91\xe2\xe0\xae\xaa\xa0."), /* "Тестовая Строка." in CP866 */
450 D_STR_W_LEN("\x92\x85\x91\x92\x8e\x82\x80\x9f \x91\x92\x90\x8e\x8a\x80."), 1}, /* "ТЕСТОВАЯ СТРОКА." in CP866 */
451 {D_STR_W_LEN("\xd2\xe5\xf1\xf2\xee\xe2\xe0\xff \xd1\xf2\xf0\xee\xea\xe0."), /* "Тестовая Строка." in CP1251 */
452 D_STR_W_LEN("\xd2\xc5\xd1\xd2\xce\xc2\xc0\xdf \xd1\xd2\xd0\xce\xca\xc0."), 1}, /* "ТЕСТОВАЯ СТРОКА." in CP1251 */
453 {D_STR_W_LEN("\xf4\xc5\xd3\xd4\xcf\xd7\xc1\xd1 \xf3\xd4\xd2\xcf\xcb\xc1."), /* "Тестовая Строка." in KOI8-R */
454 D_STR_W_LEN("\xf4\xe5\xf3\xf4\xef\xf7\xe1\xf1 \xf3\xf4\xf2\xef\xeb\xe1."), 1}, /* "ТЕСТОВАЯ СТРОКА." in KOI8-R */
455 {D_STR_W_LEN("\xc2\xd5\xe1\xe2\xde\xd2\xd0\xef \xc1\xe2\xe0\xde\xda\xd0."), /* "Тестовая Строка." in ISO-8859-5 */
456 D_STR_W_LEN("\xc2\xb5\xc1\xc2\xbe\xb2\xb0\xcf \xc1\xc2\xc0\xbe\xba\xb0."), 1}, /* "ТЕСТОВАЯ СТРОКА." in ISO-8859-5 */
457 {D_STR_W_LEN("\xd0\xa2\xd0\xb5\xd1\x81\xd1\x82\xd0\xbe\xd0\xb2\xd0\xb0\xd1"
458 "\x8f \xd0\xa1\xd1\x82\xd1\x80\xd0\xbe\xd0\xba\xd0\xb0."), /* "Тестовая Строка." in UTF-8 */
459 D_STR_W_LEN("\xd0\xa2\xd0\x95\xd0\xa1\xd0\xa2\xd0\x9e\xd0\x92\xd0\x90\xd0"
460 "\xaf \xd0\xa1\xd0\xa2\xd0\xa0\xd0\x9e\xd0\x9a\xd0\x90."), 3} /* "ТЕСТОВАЯ СТРОКА." in UTF-8 */
461};
462
463
464int check_eq_strings(void)
465{
466 size_t t_failed = 0;
467 size_t i, j;
468 static const size_t n_checks = sizeof(eq_strings) / sizeof(eq_strings[0]);
469 int c_failed[n_checks];
470
471 memset(c_failed, 0, sizeof(c_failed));
472
473 for(j = 0; j < locale_name_count; j++)
474 {
475 set_test_locale(j); /* setlocale() can be slow! */
476 for(i = 0; i < n_checks; i++)
477 {
478 const struct two_eq_strs * const t = eq_strings + i;
479 if (c_failed[i])
480 continue; /* skip already failed checks */
481 if (!MHD_str_equal_caseless_(t->s1.str, t->s2.str))
482 {
483 t_failed++;
484 c_failed[i] = !0;
485 fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
486 " Locale: %s\n", n_prnt(t->s1.str), n_prnt(t->s2.str), get_current_locale_str());
487 }
488 else if (!MHD_str_equal_caseless_(t->s2.str, t->s1.str))
489 {
490 t_failed++;
491 c_failed[i] = !0;
492 fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned zero, while expected non-zero."
493 " Locale: %s\n", n_prnt(t->s2.str), n_prnt(t->s1.str), get_current_locale_str());
494 }
495 if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
496 printf("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") != 0 && \\\n"
497 " MHD_str_equal_caseless_(\"%s\", \"%s\") != 0\n", n_prnt(t->s1.str), n_prnt(t->s2.str),
498 n_prnt(t->s2.str), n_prnt(t->s1.str));
499 }
500 }
501 return t_failed;
502}
503
504int check_neq_strings(void)
505{
506 size_t t_failed = 0;
507 size_t i, j;
508 static const size_t n_checks = sizeof(neq_strings) / sizeof(neq_strings[0]);
509 int c_failed[n_checks];
510
511 memset(c_failed, 0, sizeof(c_failed));
512
513 for(j = 0; j < locale_name_count; j++)
514 {
515 set_test_locale(j); /* setlocale() can be slow! */
516 for(i = 0; i < n_checks; i++)
517 {
518 const struct two_neq_strs * const t = neq_strings + i;
519 if (c_failed[i])
520 continue; /* skip already failed checks */
521 if (MHD_str_equal_caseless_(t->s1.str, t->s2.str))
522 {
523 t_failed++;
524 c_failed[i] = !0;
525 fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
526 " Locale: %s\n", n_prnt(t->s1.str), n_prnt(t->s2.str), get_current_locale_str());
527 }
528 else if (MHD_str_equal_caseless_(t->s2.str, t->s1.str))
529 {
530 t_failed++;
531 c_failed[i] = !0;
532 fprintf(stderr, "FAILED: MHD_str_equal_caseless_(\"%s\", \"%s\") returned non-zero, while expected zero."
533 " Locale: %s\n", n_prnt(t->s2.str), n_prnt(t->s1.str), get_current_locale_str());
534 }
535 if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
536 printf("PASSED: MHD_str_equal_caseless_(\"%s\", \"%s\") == 0 && \\\n"
537 " MHD_str_equal_caseless_(\"%s\", \"%s\") == 0\n", n_prnt(t->s1.str), n_prnt(t->s2.str),
538 n_prnt(t->s2.str), n_prnt(t->s1.str));
539 }
540 }
541 return t_failed;
542}
543
544int check_eq_strings_n(void)
545{
546 size_t t_failed = 0;
547 size_t i, j, k;
548 static const size_t n_checks = sizeof(eq_strings) / sizeof(eq_strings[0]);
549 int c_failed[n_checks];
550
551 memset(c_failed, 0, sizeof(c_failed));
552
553 for(j = 0; j < locale_name_count; j++)
554 {
555 set_test_locale(j); /* setlocale() can be slow! */
556 for(i = 0; i < n_checks; i++)
557 {
558 size_t m_len;
559 const struct two_eq_strs * const t = eq_strings + i;
560 m_len = (t->s1.len > t->s2.len) ? t->s1.len : t->s2.len;
561 for(k = 0; k <= m_len + 1 && !c_failed[i]; k++)
562 {
563 if (!MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
564 {
565 t_failed++;
566 c_failed[i] = !0;
567 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
568 " while expected non-zero. Locale: %s\n",
569 n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
570 }
571 else if (!MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
572 {
573 t_failed++;
574 c_failed[i] = !0;
575 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
576 " while expected non-zero. Locale: %s\n",
577 n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
578 }
579 }
580 if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
581 printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
582 " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
583 n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) m_len + 1);
584 }
585 }
586 return t_failed;
587}
588
589int check_neq_strings_n(void)
590{
591 size_t t_failed = 0;
592 size_t i, j, k;
593 static const size_t n_checks = sizeof(neq_strings) / sizeof(neq_strings[0]);
594 int c_failed[n_checks];
595
596 memset(c_failed, 0, sizeof(c_failed));
597
598 for(j = 0; j < locale_name_count; j++)
599 {
600 set_test_locale(j); /* setlocale() can be slow! */
601 for(i = 0; i < n_checks; i++)
602 {
603 size_t m_len;
604 const struct two_neq_strs * const t = neq_strings + i;
605 m_len = t->s1.len > t->s2.len ? t->s1.len : t->s2.len;
606 if (t->dif_pos >= m_len)
607 {
608 fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less than "
609 "s1.len (%u) or s2.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
610 (unsigned int) t->s1.len, (unsigned int) t->s2.len);
611 return -1;
612 }
613 if (t->dif_pos > t->s1.len)
614 {
615 fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
616 "equal to s1.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
617 (unsigned int) t->s1.len);
618 return -1;
619 }
620 if (t->dif_pos > t->s2.len)
621 {
622 fprintf(stderr, "ERROR: neq_strings[%u] has wrong dif_pos (%u): dif_pos is expected to be less or "
623 "equal to s2.len (%u).\n", (unsigned int) i, (unsigned int) t->dif_pos,
624 (unsigned int) t->s2.len);
625 return -1;
626 }
627 for(k = 0; k <= m_len + 1 && !c_failed[i]; k++)
628 {
629 if (k <= t->dif_pos)
630 {
631 if (!MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
632 {
633 t_failed++;
634 c_failed[i] = !0;
635 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
636 " while expected non-zero. Locale: %s\n",
637 n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
638 }
639 else if (!MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
640 {
641 t_failed++;
642 c_failed[i] = !0;
643 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned zero,"
644 " while expected non-zero. Locale: %s\n",
645 n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
646 }
647 }
648 else
649 {
650 if (MHD_str_equal_caseless_n_(t->s1.str, t->s2.str, k))
651 {
652 t_failed++;
653 c_failed[i] = !0;
654 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
655 " while expected zero. Locale: %s\n",
656 n_prnt(t->s1.str), n_prnt(t->s2.str), (unsigned int) k, get_current_locale_str());
657 }
658 else if (MHD_str_equal_caseless_n_(t->s2.str, t->s1.str, k))
659 {
660 t_failed++;
661 c_failed[i] = !0;
662 fprintf(stderr, "FAILED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", %u) returned non-zero,"
663 " while expected zero. Locale: %s\n",
664 n_prnt(t->s2.str), n_prnt(t->s1.str), (unsigned int) k, get_current_locale_str());
665 }
666 }
667 }
668 if (verbose > 1 && j == locale_name_count - 1 && !c_failed[i])
669 {
670 printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0 && \\\n"
671 " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) != 0, where N is 0..%u\n",
672 n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str),
673 (unsigned int) t->dif_pos);
674
675 printf("PASSED: MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0 && \\\n"
676 " MHD_str_equal_caseless_n_(\"%s\", \"%s\", N) == 0, where N is %u..%u\n",
677 n_prnt(t->s1.str), n_prnt(t->s2.str), n_prnt(t->s2.str), n_prnt(t->s1.str),
678 (unsigned int) t->dif_pos + 1, (unsigned int) m_len + 1);
679 }
680 }
681 }
682 return t_failed;
683}
684
685/*
686 * Run eq/neq strings tests
687 */
688int run_eq_neq_str_tests(void)
689{
690 int str_equal_caseless_fails = 0;
691 int str_equal_caseless_n_fails = 0;
692 int res;
693
694 res = check_eq_strings();
695 if (res != 0)
696 {
697 if (res < 0)
698 {
699 fprintf(stderr, "ERROR: test internal error in check_eq_strings().\n");
700 return 99;
701 }
702 str_equal_caseless_fails += res;
703 fprintf(stderr, "FAILED: testcase check_eq_strings() failed.\n\n");
704 }
705 else if (verbose > 1)
706 printf("PASSED: testcase check_eq_strings() successfully passed.\n\n");
707
708 res = check_neq_strings();
709 if (res != 0)
710 {
711 if (res < 0)
712 {
713 fprintf(stderr, "ERROR: test internal error in check_neq_strings().\n");
714 return 99;
715 }
716 str_equal_caseless_fails += res;
717 fprintf(stderr, "FAILED: testcase check_neq_strings() failed.\n\n");
718 }
719 else if (verbose > 1)
720 printf("PASSED: testcase check_neq_strings() successfully passed.\n\n");
721
722 if (str_equal_caseless_fails)
723 fprintf(stderr, "FAILED: function MHD_str_equal_caseless_() failed %d time%s.\n\n",
724 str_equal_caseless_fails, str_equal_caseless_fails == 1 ? "" : "s");
725 else if (verbose > 0)
726 printf("PASSED: function MHD_str_equal_caseless_() successfully passed all checks.\n\n");
727
728 res = check_eq_strings_n();
729 if (res != 0)
730 {
731 if (res < 0)
732 {
733 fprintf(stderr, "ERROR: test internal error in check_eq_strings_n().\n");
734 return 99;
735 }
736 str_equal_caseless_n_fails += res;
737 fprintf(stderr, "FAILED: testcase check_eq_strings_n() failed.\n\n");
738 }
739 else if (verbose > 1)
740 printf("PASSED: testcase check_eq_strings_n() successfully passed.\n\n");
741
742 res = check_neq_strings_n();
743 if (res != 0)
744 {
745 if (res < 0)
746 {
747 fprintf(stderr, "ERROR: test internal error in check_neq_strings_n().\n");
748 return 99;
749 }
750 str_equal_caseless_n_fails += res;
751 fprintf(stderr, "FAILED: testcase check_neq_strings_n() failed.\n\n");
752 }
753 else if (verbose > 1)
754 printf("PASSED: testcase check_neq_strings_n() successfully passed.\n\n");
755
756 if (str_equal_caseless_n_fails)
757 fprintf(stderr, "FAILED: function MHD_str_equal_caseless_n_() failed %d time%s.\n\n",
758 str_equal_caseless_n_fails, str_equal_caseless_n_fails == 1 ? "" : "s");
759 else if (verbose > 0)
760 printf("PASSED: function MHD_str_equal_caseless_n_() successfully passed all checks.\n\n");
761
762 if (str_equal_caseless_fails || str_equal_caseless_n_fails)
763 {
764 if (verbose > 0)
765 printf("At least one test failed.\n");
766
767 return 1;
768 }
769
770 if (verbose > 0)
771 printf("All tests passed successfully.\n");
772
773 return 0;
774}
775
776int main(int argc, char * argv[])
777{
778 if (has_param(argc, argv, "-v") || has_param(argc, argv, "--verbose") || has_param(argc, argv, "--verbose1"))
779 verbose = 1;
780 if (has_param(argc, argv, "-vv") || has_param(argc, argv, "--verbose2"))
781 verbose = 2;
782 if (has_param(argc, argv, "-vvv") || has_param(argc, argv, "--verbose3"))
783 verbose = 3;
784
785 return run_eq_neq_str_tests();
786}