libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

test_str_pct.c (38205B)


      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 
     40 static char tmp_bufs[4][4 * 1024]; /* should be enough for testing */
     41 static size_t buf_idx = 0;
     42 
     43 /* print non-printable chars as char codes */
     44 static char *
     45 n_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 */
     96 static unsigned int
     97 expect_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 
    511 static unsigned int
    512 check_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 
    591 static unsigned int
    592 check_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 */
    693 static unsigned int
    694 expect_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 
   1028 static unsigned int
   1029 check_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 
   1049 int
   1050 main (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 }