aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/test_str_pct.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/test_str_pct.c')
-rw-r--r--src/microhttpd/test_str_pct.c1060
1 files changed, 1060 insertions, 0 deletions
diff --git a/src/microhttpd/test_str_pct.c b/src/microhttpd/test_str_pct.c
new file mode 100644
index 00000000..8c3375ce
--- /dev/null
+++ b/src/microhttpd/test_str_pct.c
@@ -0,0 +1,1060 @@
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2022 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/test_str_pct.c
22 * @brief Unit tests for percent (URL) encoded strings processing
23 * @author Karlson2k (Evgeny Grin)
24 */
25
26#include "mhd_options.h"
27#include <string.h>
28#include <stdio.h>
29#include "mhd_str.h"
30#include "mhd_assert.h"
31
32#ifndef MHD_STATICSTR_LEN_
33/**
34 * Determine length of static string / macro strings at compile time.
35 */
36#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
37#endif /* ! MHD_STATICSTR_LEN_ */
38
39
40static char tmp_bufs[4][4 * 1024]; /* should be enough for testing */
41static size_t buf_idx = 0;
42
43/* print non-printable chars as char codes */
44static char *
45n_prnt (const char *str, size_t len)
46{
47 static char *buf; /* should be enough for testing */
48 static const size_t buf_size = sizeof(tmp_bufs[0]);
49 size_t r_pos = 0;
50 size_t w_pos = 0;
51 if (++buf_idx >= (sizeof(tmp_bufs) / sizeof(tmp_bufs[0])))
52 buf_idx = 0;
53 buf = tmp_bufs[buf_idx];
54
55 while (len > r_pos && w_pos + 1 < buf_size)
56 {
57 const unsigned char c = (unsigned char) str[r_pos];
58 if ((c == '\\') || (c == '"') )
59 {
60 if (w_pos + 2 >= buf_size)
61 break;
62 buf[w_pos++] = '\\';
63 buf[w_pos++] = (char) c;
64 }
65 else if ((c >= 0x20) && (c <= 0x7E) )
66 buf[w_pos++] = (char) c;
67 else
68 {
69 if (w_pos + 4 >= buf_size)
70 break;
71 if (snprintf (buf + w_pos, buf_size - w_pos, "\\x%02hX", (short unsigned
72 int) c) != 4)
73 break;
74 w_pos += 4;
75 }
76 r_pos++;
77 }
78
79 if (len != r_pos)
80 { /* not full string is printed */
81 /* enough space for "..." ? */
82 if (w_pos + 3 > buf_size)
83 w_pos = buf_size - 4;
84 buf[w_pos++] = '.';
85 buf[w_pos++] = '.';
86 buf[w_pos++] = '.';
87 }
88 buf[w_pos] = 0;
89 return buf;
90}
91
92
93#define TEST_BIN_MAX_SIZE 1024
94
95/* return zero if succeed, number of failures otherwise */
96static unsigned int
97expect_decoded_n (const char *const encoded, const size_t encoded_len,
98 const char *const decoded, const size_t decoded_size,
99 const unsigned int line_num)
100{
101 static const char fill_chr = '#';
102 static char buf[TEST_BIN_MAX_SIZE];
103 size_t res_size;
104 unsigned int ret;
105
106 mhd_assert (NULL != encoded);
107 mhd_assert (NULL != decoded);
108 mhd_assert (TEST_BIN_MAX_SIZE > decoded_size + 1);
109 mhd_assert (TEST_BIN_MAX_SIZE > encoded_len + 1);
110 mhd_assert (encoded_len >= decoded_size);
111
112 ret = 0;
113
114 /* check MHD_str_pct_decode_strict_n_() with small out buffer */
115 if (1)
116 {
117 unsigned int check_res = 0;
118
119 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
120 res_size = MHD_str_pct_decode_strict_n_ (encoded, encoded_len, buf,
121 decoded_size + 1);
122 if (res_size != decoded_size)
123 {
124 check_res = 1;
125 fprintf (stderr,
126 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
127 "Wrong returned value:\n");
128 }
129 else
130 {
131 if (fill_chr != buf[res_size])
132 {
133 check_res = 1;
134 fprintf (stderr,
135 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
136 "A char written outside the buffer:\n");
137 }
138 else
139 {
140 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
141 res_size = MHD_str_pct_decode_strict_n_ (encoded, encoded_len, buf,
142 decoded_size);
143 if (res_size != decoded_size)
144 {
145 check_res = 1;
146 fprintf (stderr,
147 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
148 "Wrong returned value:\n");
149 }
150 }
151 if ((res_size == decoded_size) && (0 != decoded_size) &&
152 (0 != memcmp (buf, decoded, decoded_size)))
153 {
154 check_res = 1;
155 fprintf (stderr,
156 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
157 "Wrong output string:\n");
158 }
159 }
160 if (0 != check_res)
161 {
162 ret++;
163 fprintf (stderr,
164 "\tRESULT : MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
165 "->\"%s\", %u) -> %u\n",
166 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
167 n_prnt (buf, res_size), (unsigned) decoded_size,
168 (unsigned) res_size);
169 fprintf (stderr,
170 "\tEXPECTED: MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
171 "->\"%s\", %u) -> %u\n",
172 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
173 n_prnt (decoded, decoded_size), (unsigned) decoded_size,
174 (unsigned) decoded_size);
175 }
176 }
177
178 /* check MHD_str_pct_decode_strict_n_() with large out buffer */
179 if (1)
180 {
181 unsigned int check_res = 0;
182
183 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
184 res_size = MHD_str_pct_decode_strict_n_ (encoded, encoded_len, buf,
185 encoded_len + 1);
186 if (res_size != decoded_size)
187 {
188 check_res = 1;
189 fprintf (stderr,
190 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
191 "Wrong returned value:\n");
192 }
193 else
194 {
195 if (fill_chr != buf[res_size])
196 {
197 check_res = 1;
198 fprintf (stderr,
199 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
200 "A char written outside the buffer:\n");
201 }
202 if ((res_size == decoded_size) && (0 != decoded_size) &&
203 (0 != memcmp (buf, decoded, decoded_size)))
204 {
205 check_res = 1;
206 fprintf (stderr,
207 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
208 "Wrong output string:\n");
209 }
210 }
211 if (0 != check_res)
212 {
213 ret++;
214 fprintf (stderr,
215 "\tRESULT : MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
216 "->\"%s\", %u) -> %u\n",
217 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
218 n_prnt (buf, res_size), (unsigned) (encoded_len + 1),
219 (unsigned) res_size);
220 fprintf (stderr,
221 "\tEXPECTED: MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
222 "->\"%s\", %u) -> %u\n",
223 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
224 n_prnt (decoded, decoded_size), (unsigned) (encoded_len + 1),
225 (unsigned) decoded_size);
226 }
227 }
228
229 /* check MHD_str_pct_decode_lenient_n_() with small out buffer */
230 if (1)
231 {
232 unsigned int check_res = 0;
233 bool is_broken = true;
234
235 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
236 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
237 decoded_size + 1, &is_broken);
238 if (res_size != decoded_size)
239 {
240 check_res = 1;
241 fprintf (stderr,
242 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
243 "Wrong returned value:\n");
244 }
245 else
246 {
247 if (fill_chr != buf[res_size])
248 {
249 check_res = 1;
250 fprintf (stderr,
251 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
252 "A char written outside the buffer:\n");
253 }
254 else
255 {
256 is_broken = true;
257 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
258 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
259 decoded_size, &is_broken);
260 if (res_size != decoded_size)
261 {
262 check_res = 1;
263 fprintf (stderr,
264 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
265 "Wrong returned value:\n");
266 }
267 }
268 if (is_broken)
269 {
270 check_res = 1;
271 fprintf (stderr,
272 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
273 "Wrong 'broken_encoding' result:\n");
274 }
275 if ((res_size == decoded_size) && (0 != decoded_size) &&
276 (0 != memcmp (buf, decoded, decoded_size)))
277 {
278 check_res = 1;
279 fprintf (stderr,
280 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
281 "Wrong output string:\n");
282 }
283 }
284 if (0 != check_res)
285 {
286 ret++;
287 fprintf (stderr,
288 "\tRESULT : MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
289 "->\"%s\", %u, ->%s) -> %u\n",
290 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
291 n_prnt (buf, res_size), (unsigned) decoded_size,
292 is_broken ? "true" : "false",
293 (unsigned) res_size);
294 fprintf (stderr,
295 "\tEXPECTED: MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
296 "->\"%s\", %u, ->false) -> %u\n",
297 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
298 n_prnt (decoded, decoded_size), (unsigned) decoded_size,
299 (unsigned) decoded_size);
300 }
301 }
302
303 /* check MHD_str_pct_decode_lenient_n_() with large out buffer */
304 if (1)
305 {
306 unsigned int check_res = 0;
307 bool is_broken = true;
308
309 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
310 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
311 encoded_len + 1, &is_broken);
312 if (res_size != decoded_size)
313 {
314 check_res = 1;
315 fprintf (stderr,
316 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
317 "Wrong returned value:\n");
318 }
319 else
320 {
321 if (fill_chr != buf[res_size])
322 {
323 check_res = 1;
324 fprintf (stderr,
325 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
326 "A char written outside the buffer:\n");
327 }
328 if (is_broken)
329 {
330 check_res = 1;
331 fprintf (stderr,
332 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
333 "Wrong 'broken_encoding' result:\n");
334 }
335 if ((res_size == decoded_size) && (0 != decoded_size) &&
336 (0 != memcmp (buf, decoded, decoded_size)))
337 {
338 check_res = 1;
339 fprintf (stderr,
340 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
341 "Wrong output string:\n");
342 }
343 }
344 if (0 != check_res)
345 {
346 ret++;
347 fprintf (stderr,
348 "\tRESULT : MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
349 "->\"%s\", %u, ->%s) -> %u\n",
350 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
351 n_prnt (buf, res_size), (unsigned) (encoded_len + 1),
352 is_broken ? "true" : "false",
353 (unsigned) res_size);
354 fprintf (stderr,
355 "\tEXPECTED: MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
356 "->\"%s\", %u, ->false) -> %u\n",
357 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
358 n_prnt (decoded, decoded_size), (unsigned) (encoded_len + 1),
359 (unsigned) decoded_size);
360 }
361 }
362
363 if (strlen (encoded) == encoded_len)
364 {
365 /* check MHD_str_pct_decode_in_place_strict_() */
366 if (1)
367 {
368 unsigned int check_res = 0;
369
370 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
371 memcpy (buf, encoded, encoded_len);
372 buf[encoded_len] = 0;
373 res_size = MHD_str_pct_decode_in_place_strict_ (buf);
374 if (res_size != decoded_size)
375 {
376 check_res = 1;
377 fprintf (stderr,
378 "'MHD_str_pct_decode_in_place_strict_ ()' FAILED: "
379 "Wrong returned value:\n");
380 }
381 else
382 {
383 if (0 != buf[res_size])
384 {
385 check_res = 1;
386 fprintf (stderr,
387 "'MHD_str_pct_decode_in_place_strict_ ()' FAILED: "
388 "The result is not zero-terminated:\n");
389 }
390 if (((res_size + 1) < encoded_len) ?
391 (encoded[res_size + 1] != buf[res_size + 1]) :
392 (fill_chr != buf[res_size + 1]))
393 {
394 check_res = 1;
395 fprintf (stderr,
396 "'MHD_str_pct_decode_in_place_strict_ ()' FAILED: "
397 "A char written outside the buffer:\n");
398 }
399 if ((res_size == decoded_size) && (0 != decoded_size) &&
400 (0 != memcmp (buf, decoded, decoded_size)))
401 {
402 check_res = 1;
403 fprintf (stderr,
404 "'MHD_str_pct_decode_in_place_strict_ ()' FAILED: "
405 "Wrong output string:\n");
406 }
407 }
408 if (0 != check_res)
409 {
410 ret++;
411 fprintf (stderr,
412 "\tRESULT : MHD_str_pct_decode_in_place_strict_ (\"%s\" "
413 "-> \"%s\") -> %u\n",
414 n_prnt (encoded, encoded_len),
415 n_prnt (buf, res_size),
416 (unsigned) res_size);
417 fprintf (stderr,
418 "\tEXPECTED: MHD_str_pct_decode_in_place_strict_ (\"%s\" "
419 "-> \"%s\") -> %u\n",
420 n_prnt (encoded, encoded_len),
421 n_prnt (decoded, decoded_size),
422 (unsigned) decoded_size);
423 }
424 }
425
426 /* check MHD_str_pct_decode_in_place_lenient_() */
427 if (1)
428 {
429 unsigned int check_res = 0;
430 bool is_broken = true;
431
432 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
433 memcpy (buf, encoded, encoded_len);
434 buf[encoded_len] = 0;
435 res_size = MHD_str_pct_decode_in_place_lenient_ (buf, &is_broken);
436 if (res_size != decoded_size)
437 {
438 check_res = 1;
439 fprintf (stderr,
440 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
441 "Wrong returned value:\n");
442 }
443 else
444 {
445 if (0 != buf[res_size])
446 {
447 check_res = 1;
448 fprintf (stderr,
449 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
450 "The result is not zero-terminated:\n");
451 }
452 if (((res_size + 1) < encoded_len) ?
453 (encoded[res_size + 1] != buf[res_size + 1]) :
454 (fill_chr != buf[res_size + 1]))
455 {
456 check_res = 1;
457 fprintf (stderr,
458 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
459 "A char written outside the buffer:\n");
460 }
461 if (is_broken)
462 {
463 check_res = 1;
464 fprintf (stderr,
465 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
466 "Wrong 'broken_encoding' result:\n");
467 }
468 if ((res_size == decoded_size) && (0 != decoded_size) &&
469 (0 != memcmp (buf, decoded, decoded_size)))
470 {
471 check_res = 1;
472 fprintf (stderr,
473 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
474 "Wrong output string:\n");
475 }
476 }
477 if (0 != check_res)
478 {
479 ret++;
480 fprintf (stderr,
481 "\tRESULT : MHD_str_pct_decode_in_place_lenient_ (\"%s\" "
482 "-> \"%s\", ->%s) -> %u\n",
483 n_prnt (encoded, encoded_len),
484 n_prnt (buf, res_size),
485 is_broken ? "true" : "false",
486 (unsigned) res_size);
487 fprintf (stderr,
488 "\tEXPECTED: MHD_str_pct_decode_in_place_lenient_ (\"%s\" "
489 "-> \"%s\", ->false) -> %u\n",
490 n_prnt (encoded, encoded_len),
491 n_prnt (decoded, decoded_size),
492 (unsigned) decoded_size);
493 }
494 }
495 }
496
497 if (0 != ret)
498 {
499 fprintf (stderr,
500 "The check is at line: %u\n\n", line_num);
501 }
502 return ret;
503}
504
505
506#define expect_decoded(e,d) \
507 expect_decoded_n(e,MHD_STATICSTR_LEN_(e),\
508 d,MHD_STATICSTR_LEN_(d), \
509 __LINE__)
510
511static unsigned int
512check_decode_str (void)
513{
514 unsigned int r = 0; /**< The number of errors */
515
516 r += expect_decoded ("", "");
517
518 /* Base sequences without percent symbol */
519 r += expect_decoded ("aaa", "aaa");
520 r += expect_decoded ("bbb", "bbb");
521 r += expect_decoded ("ccc", "ccc");
522 r += expect_decoded ("ddd", "ddd");
523 r += expect_decoded ("lll", "lll");
524 r += expect_decoded ("mmm", "mmm");
525 r += expect_decoded ("nnn", "nnn");
526 r += expect_decoded ("ooo", "ooo");
527 r += expect_decoded ("www", "www");
528 r += expect_decoded ("xxx", "xxx");
529 r += expect_decoded ("yyy", "yyy");
530 r += expect_decoded ("zzz", "zzz");
531 r += expect_decoded ("AAA", "AAA");
532 r += expect_decoded ("GGG", "GGG");
533 r += expect_decoded ("MMM", "MMM");
534 r += expect_decoded ("TTT", "TTT");
535 r += expect_decoded ("ZZZ", "ZZZ");
536 r += expect_decoded ("012", "012");
537 r += expect_decoded ("345", "345");
538 r += expect_decoded ("678", "678");
539 r += expect_decoded ("901", "901");
540 r += expect_decoded ("aaaaaa", "aaaaaa");
541 r += expect_decoded ("bbbbbb", "bbbbbb");
542 r += expect_decoded ("cccccc", "cccccc");
543 r += expect_decoded ("dddddd", "dddddd");
544 r += expect_decoded ("llllll", "llllll");
545 r += expect_decoded ("mmmmmm", "mmmmmm");
546 r += expect_decoded ("nnnnnn", "nnnnnn");
547 r += expect_decoded ("oooooo", "oooooo");
548 r += expect_decoded ("wwwwww", "wwwwww");
549 r += expect_decoded ("xxxxxx", "xxxxxx");
550 r += expect_decoded ("yyyyyy", "yyyyyy");
551 r += expect_decoded ("zzzzzz", "zzzzzz");
552 r += expect_decoded ("AAAAAA", "AAAAAA");
553 r += expect_decoded ("GGGGGG", "GGGGGG");
554 r += expect_decoded ("MMMMMM", "MMMMMM");
555 r += expect_decoded ("TTTTTT", "TTTTTT");
556 r += expect_decoded ("ZZZZZZ", "ZZZZZZ");
557 r += expect_decoded ("012012", "012012");
558 r += expect_decoded ("345345", "345345");
559 r += expect_decoded ("678678", "678678");
560 r += expect_decoded ("901901", "901901");
561 r += expect_decoded ("a", "a");
562 r += expect_decoded ("bc", "bc");
563 r += expect_decoded ("DEFG", "DEFG");
564 r += expect_decoded ("123t", "123t");
565 r += expect_decoded ("12345", "12345");
566 r += expect_decoded ("TestStr", "TestStr");
567 r += expect_decoded ("Teststring", "Teststring");
568 r += expect_decoded ("Teststring.", "Teststring.");
569 r += expect_decoded ("Longerstring", "Longerstring");
570 r += expect_decoded ("Longerstring.", "Longerstring.");
571 r += expect_decoded ("Longerstring2.", "Longerstring2.");
572
573 /* Simple percent-encoded strings */
574 r += expect_decoded ("Test%20string", "Test string");
575 r += expect_decoded ("Test%3Fstring.", "Test?string.");
576 r += expect_decoded ("100%25", "100%");
577 r += expect_decoded ("a%2C%20b%3Dc%26e%3Dg", "a, b=c&e=g");
578 r += expect_decoded ("%20%21%23%24%25%26%27%28%29%2A%2B%2C"
579 "%2F%3A%3B%3D%3F%40%5B%5D%09",
580 " !#$%&'()*+,/:;=?@[]\t");
581
582 return r;
583}
584
585
586#define expect_decoded_arr(e,a) \
587 expect_decoded_n(e,MHD_STATICSTR_LEN_(e),\
588 (const char *)a,(sizeof(a)/sizeof(a[0])), \
589 __LINE__)
590
591static unsigned int
592check_decode_bin (void)
593{
594 unsigned int r = 0; /**< The number of errors */
595
596 if (1)
597 {
598 static const uint8_t bin[256] =
599 {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe,
600 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
601 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
602 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
603 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
604 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
605 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
606 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62,
607 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
608 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
609 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
610 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
611 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
612 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
613 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
614 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2,
615 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
616 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
617 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
618 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2,
619 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
620 0xff };
621 /* The lower case */
622 r += expect_decoded_arr ("%00%01%02%03%04%05%06%07%08%09%0a%0b%0c%0d%0e" \
623 "%0f%10%11%12%13%14%15%16%17%18%19%1a%1b%1c%1d" \
624 "%1e%1f%20%21%22%23%24%25%26%27%28%29%2a%2b%2c" \
625 "%2d%2e%2f%30%31%32%33%34%35%36%37%38%39%3a%3b" \
626 "%3c%3d%3e%3f%40%41%42%43%44%45%46%47%48%49%4a" \
627 "%4b%4c%4d%4e%4f%50%51%52%53%54%55%56%57%58%59" \
628 "%5a%5b%5c%5d%5e%5f%60%61%62%63%64%65%66%67%68" \
629 "%69%6a%6b%6c%6d%6e%6f%70%71%72%73%74%75%76%77" \
630 "%78%79%7a%7b%7c%7d%7e%7f%80%81%82%83%84%85%86" \
631 "%87%88%89%8a%8b%8c%8d%8e%8f%90%91%92%93%94%95" \
632 "%96%97%98%99%9a%9b%9c%9d%9e%9f%a0%a1%a2%a3%a4" \
633 "%a5%a6%a7%a8%a9%aa%ab%ac%ad%ae%af%b0%b1%b2%b3" \
634 "%b4%b5%b6%b7%b8%b9%ba%bb%bc%bd%be%bf%c0%c1%c2" \
635 "%c3%c4%c5%c6%c7%c8%c9%ca%cb%cc%cd%ce%cf%d0%d1" \
636 "%d2%d3%d4%d5%d6%d7%d8%d9%da%db%dc%dd%de%df%e0" \
637 "%e1%e2%e3%e4%e5%e6%e7%e8%e9%ea%eb%ec%ed%ee%ef" \
638 "%f0%f1%f2%f3%f4%f5%f6%f7%f8%f9%fa%fb%fc%fd%fe" \
639 "%ff", bin);
640 }
641
642 if (1)
643 {
644 static const uint8_t bin[256] =
645 {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe,
646 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
647 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
648 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32,
649 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
650 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
651 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
652 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62,
653 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
654 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
655 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86,
656 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
657 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
658 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
659 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
660 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2,
661 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce,
662 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
663 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
664 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2,
665 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe,
666 0xff };
667 /* The upper case */
668 r += expect_decoded_arr ("%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E" \
669 "%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D" \
670 "%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C" \
671 "%2D%2E%2F%30%31%32%33%34%35%36%37%38%39%3A%3B" \
672 "%3C%3D%3E%3F%40%41%42%43%44%45%46%47%48%49%4A" \
673 "%4B%4C%4D%4E%4F%50%51%52%53%54%55%56%57%58%59" \
674 "%5A%5B%5C%5D%5E%5F%60%61%62%63%64%65%66%67%68" \
675 "%69%6A%6B%6C%6D%6E%6F%70%71%72%73%74%75%76%77" \
676 "%78%79%7A%7B%7C%7D%7E%7F%80%81%82%83%84%85%86" \
677 "%87%88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95" \
678 "%96%97%98%99%9A%9B%9C%9D%9E%9F%A0%A1%A2%A3%A4" \
679 "%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3" \
680 "%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2" \
681 "%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%D0%D1" \
682 "%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0" \
683 "%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" \
684 "%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE" \
685 "%FF", bin);
686 }
687
688 return r;
689}
690
691
692/* return zero if succeed, number of failures otherwise */
693static unsigned int
694expect_decoded_bad_n (const char *const encoded, const size_t encoded_len,
695 const char *const decoded, const size_t decoded_size,
696 const unsigned int line_num)
697{
698 static const char fill_chr = '#';
699 static char buf[TEST_BIN_MAX_SIZE];
700 size_t res_size;
701 unsigned int ret;
702
703 mhd_assert (NULL != encoded);
704 mhd_assert (NULL != decoded);
705 mhd_assert (TEST_BIN_MAX_SIZE > decoded_size + 1);
706 mhd_assert (TEST_BIN_MAX_SIZE > encoded_len + 1);
707 mhd_assert (encoded_len >= decoded_size);
708
709 ret = 0;
710
711 /* check MHD_str_pct_decode_strict_n_() with small out buffer */
712 if (1)
713 {
714 unsigned int check_res = 0;
715
716 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
717 res_size = MHD_str_pct_decode_strict_n_ (encoded, encoded_len, buf,
718 decoded_size);
719 if (res_size != 0)
720 {
721 check_res = 1;
722 fprintf (stderr,
723 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
724 "Wrong returned value:\n");
725 }
726 if (0 != check_res)
727 {
728 ret++;
729 fprintf (stderr,
730 "\tRESULT : MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
731 "->\"%s\", %u) -> %u\n",
732 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
733 n_prnt (buf, res_size), (unsigned) decoded_size,
734 (unsigned) res_size);
735 fprintf (stderr,
736 "\tEXPECTED: MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
737 "->(not defined), %u) -> 0\n",
738 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
739 (unsigned) decoded_size);
740 }
741 }
742
743 /* check MHD_str_pct_decode_strict_n_() with large out buffer */
744 if (1)
745 {
746 unsigned int check_res = 0;
747
748 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
749 res_size = MHD_str_pct_decode_strict_n_ (encoded, encoded_len, buf,
750 encoded_len + 1);
751 if (res_size != 0)
752 {
753 check_res = 1;
754 fprintf (stderr,
755 "'MHD_str_pct_decode_strict_n_ ()' FAILED: "
756 "Wrong returned value:\n");
757 }
758 if (0 != check_res)
759 {
760 ret++;
761 fprintf (stderr,
762 "\tRESULT : MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
763 "->\"%s\", %u) -> %u\n",
764 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
765 n_prnt (buf, res_size), (unsigned) (encoded_len + 1),
766 (unsigned) res_size);
767 fprintf (stderr,
768 "\tEXPECTED: MHD_str_pct_decode_strict_n_ (\"%s\", %u, "
769 "->(not defined), %u) -> 0\n",
770 n_prnt (encoded, encoded_len), (unsigned) (encoded_len + 1),
771 (unsigned) decoded_size);
772 }
773 }
774
775 /* check MHD_str_pct_decode_lenient_n_() with small out buffer */
776 if (1)
777 {
778 unsigned int check_res = 0;
779 bool is_broken = false;
780
781 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
782 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
783 decoded_size + 1, &is_broken);
784 if (res_size != decoded_size)
785 {
786 check_res = 1;
787 fprintf (stderr,
788 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
789 "Wrong returned value:\n");
790 }
791 else
792 {
793 if (fill_chr != buf[res_size])
794 {
795 check_res = 1;
796 fprintf (stderr,
797 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
798 "A char written outside the buffer:\n");
799 }
800 else
801 {
802 is_broken = false;
803 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
804 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
805 decoded_size, &is_broken);
806 if (res_size != decoded_size)
807 {
808 check_res = 1;
809 fprintf (stderr,
810 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
811 "Wrong returned value:\n");
812 }
813 }
814 if (! is_broken)
815 {
816 check_res = 1;
817 fprintf (stderr,
818 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
819 "Wrong 'broken_encoding' result:\n");
820 }
821 if ((res_size == decoded_size) && (0 != decoded_size) &&
822 (0 != memcmp (buf, decoded, decoded_size)))
823 {
824 check_res = 1;
825 fprintf (stderr,
826 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
827 "Wrong output string:\n");
828 }
829 }
830 if (0 != check_res)
831 {
832 ret++;
833 fprintf (stderr,
834 "\tRESULT : MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
835 "->\"%s\", %u, ->%s) -> %u\n",
836 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
837 n_prnt (buf, res_size), (unsigned) decoded_size,
838 is_broken ? "true" : "false",
839 (unsigned) res_size);
840 fprintf (stderr,
841 "\tEXPECTED: MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
842 "->\"%s\", %u, ->true) -> %u\n",
843 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
844 n_prnt (decoded, decoded_size), (unsigned) decoded_size,
845 (unsigned) decoded_size);
846 }
847 }
848
849 /* check MHD_str_pct_decode_lenient_n_() with large out buffer */
850 if (1)
851 {
852 unsigned int check_res = 0;
853 bool is_broken = false;
854
855 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
856 res_size = MHD_str_pct_decode_lenient_n_ (encoded, encoded_len, buf,
857 encoded_len + 1, &is_broken);
858 if (res_size != decoded_size)
859 {
860 check_res = 1;
861 fprintf (stderr,
862 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
863 "Wrong returned value:\n");
864 }
865 else
866 {
867 if (fill_chr != buf[res_size])
868 {
869 check_res = 1;
870 fprintf (stderr,
871 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
872 "A char written outside the buffer:\n");
873 }
874 if (! is_broken)
875 {
876 check_res = 1;
877 fprintf (stderr,
878 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
879 "Wrong 'broken_encoding' result:\n");
880 }
881 if ((res_size == decoded_size) && (0 != decoded_size) &&
882 (0 != memcmp (buf, decoded, decoded_size)))
883 {
884 check_res = 1;
885 fprintf (stderr,
886 "'MHD_str_pct_decode_lenient_n_ ()' FAILED: "
887 "Wrong output string:\n");
888 }
889 }
890 if (0 != check_res)
891 {
892 ret++;
893 fprintf (stderr,
894 "\tRESULT : MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
895 "->\"%s\", %u, ->%s) -> %u\n",
896 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
897 n_prnt (buf, res_size), (unsigned) (encoded_len + 1),
898 is_broken ? "true" : "false",
899 (unsigned) res_size);
900 fprintf (stderr,
901 "\tEXPECTED: MHD_str_pct_decode_lenient_n_ (\"%s\", %u, "
902 "->\"%s\", %u, ->true) -> %u\n",
903 n_prnt (encoded, encoded_len), (unsigned) encoded_len,
904 n_prnt (decoded, decoded_size), (unsigned) (encoded_len + 1),
905 (unsigned) decoded_size);
906 }
907 }
908
909 if (strlen (encoded) == encoded_len)
910 {
911 /* check MHD_str_pct_decode_in_place_strict_() */
912 if (1)
913 {
914 unsigned int check_res = 0;
915
916 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
917 memcpy (buf, encoded, encoded_len);
918 buf[encoded_len] = 0;
919 res_size = MHD_str_pct_decode_in_place_strict_ (buf);
920 if (res_size != 0)
921 {
922 check_res = 1;
923 fprintf (stderr,
924 "'MHD_str_pct_decode_in_place_strict_ ()' FAILED: "
925 "Wrong returned value:\n");
926 }
927 if (0 != check_res)
928 {
929 ret++;
930 fprintf (stderr,
931 "\tRESULT : MHD_str_pct_decode_in_place_strict_ (\"%s\" "
932 "-> \"%s\") -> %u\n",
933 n_prnt (encoded, encoded_len),
934 n_prnt (buf, res_size),
935 (unsigned) res_size);
936 fprintf (stderr,
937 "\tEXPECTED: MHD_str_pct_decode_in_place_strict_ (\"%s\" "
938 "-> (not defined)) -> 0\n",
939 n_prnt (encoded, encoded_len));
940 }
941 }
942
943 /* check MHD_str_pct_decode_in_place_lenient_() */
944 if (1)
945 {
946 unsigned int check_res = 0;
947 bool is_broken = false;
948
949 memset (buf, fill_chr, sizeof(buf)); /* Fill buffer with some character */
950 memcpy (buf, encoded, encoded_len);
951 buf[encoded_len] = 0;
952 res_size = MHD_str_pct_decode_in_place_lenient_ (buf, &is_broken);
953 if (res_size != decoded_size)
954 {
955 check_res = 1;
956 fprintf (stderr,
957 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
958 "Wrong returned value:\n");
959 }
960 else
961 {
962 if (0 != buf[res_size])
963 {
964 check_res = 1;
965 fprintf (stderr,
966 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
967 "The result is not zero-terminated:\n");
968 }
969 if (((res_size + 1) < encoded_len) ?
970 (encoded[res_size + 1] != buf[res_size + 1]) :
971 (fill_chr != buf[res_size + 1]))
972 {
973 check_res = 1;
974 fprintf (stderr,
975 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
976 "A char written outside the buffer:\n");
977 }
978 if (! is_broken)
979 {
980 check_res = 1;
981 fprintf (stderr,
982 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
983 "Wrong 'broken_encoding' result:\n");
984 }
985 if ((res_size == decoded_size) && (0 != decoded_size) &&
986 (0 != memcmp (buf, decoded, decoded_size)))
987 {
988 check_res = 1;
989 fprintf (stderr,
990 "'MHD_str_pct_decode_in_place_lenient_ ()' FAILED: "
991 "Wrong output string:\n");
992 }
993 }
994 if (0 != check_res)
995 {
996 ret++;
997 fprintf (stderr,
998 "\tRESULT : MHD_str_pct_decode_in_place_lenient_ (\"%s\" "
999 "-> \"%s\", ->%s) -> %u\n",
1000 n_prnt (encoded, encoded_len),
1001 n_prnt (buf, res_size),
1002 is_broken ? "true" : "false",
1003 (unsigned) res_size);
1004 fprintf (stderr,
1005 "\tEXPECTED: MHD_str_pct_decode_in_place_lenient_ (\"%s\" "
1006 "-> \"%s\", ->true) -> %u\n",
1007 n_prnt (encoded, encoded_len),
1008 n_prnt (decoded, decoded_size),
1009 (unsigned) decoded_size);
1010 }
1011 }
1012 }
1013
1014 if (0 != ret)
1015 {
1016 fprintf (stderr,
1017 "The check is at line: %u\n\n", line_num);
1018 }
1019 return ret;
1020}
1021
1022
1023#define expect_decoded_bad(e,d) \
1024 expect_decoded_bad_n(e,MHD_STATICSTR_LEN_(e),\
1025 d,MHD_STATICSTR_LEN_(d), \
1026 __LINE__)
1027
1028static unsigned int
1029check_decode_bad_str (void)
1030{
1031 unsigned int r = 0; /**< The number of errors */
1032
1033 r += expect_decoded_bad ("50%/50%", "50%/50%");
1034 r += expect_decoded_bad ("This is 100% incorrect.",
1035 "This is 100% incorrect.");
1036 r += expect_decoded_bad ("Some %%", "Some %%");
1037 r += expect_decoded_bad ("1 %", "1 %");
1038 r += expect_decoded_bad ("%", "%");
1039 r += expect_decoded_bad ("%a", "%a");
1040 r += expect_decoded_bad ("%0", "%0");
1041 r += expect_decoded_bad ("%0x", "%0x");
1042 r += expect_decoded_bad ("%FX", "%FX");
1043 r += expect_decoded_bad ("Valid%20and%2invalid", "Valid and%2invalid");
1044
1045 return r;
1046}
1047
1048
1049int
1050main (int argc, char *argv[])
1051{
1052 unsigned int errcount = 0;
1053 (void) argc; (void) argv; /* Unused. Silent compiler warning. */
1054 errcount += check_decode_str ();
1055 errcount += check_decode_bin ();
1056 errcount += check_decode_bad_str ();
1057 if (0 == errcount)
1058 printf ("All tests have been passed without errors.\n");
1059 return errcount == 0 ? 0 : 1;
1060}