libmicrohttpd

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

test_str_pct.c (38372B)


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