libmicrohttpd

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

test_str_quote.c (31455B)


      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_quote.c
     22  * @brief  Unit tests for quoted 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 #define TEST_STR_MAX_LEN 1024
     45 
     46 /* return zero if succeed, non-zero otherwise */
     47 static unsigned int
     48 expect_result_unquote_n (const char *const quoted, const size_t quoted_len,
     49                          const char *const unquoted, const size_t unquoted_len,
     50                          const unsigned int line_num)
     51 {
     52   static char buf[TEST_STR_MAX_LEN];
     53   size_t res_len;
     54   unsigned int ret1;
     55   unsigned int ret2;
     56   unsigned int ret3;
     57   unsigned int ret4;
     58 
     59   mhd_assert (NULL != quoted);
     60   mhd_assert (NULL != unquoted);
     61   mhd_assert (TEST_STR_MAX_LEN > quoted_len);
     62   mhd_assert (quoted_len >= unquoted_len);
     63 
     64   /* First check: MHD_str_unquote () */
     65   ret1 = 0;
     66   memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */
     67   res_len = MHD_str_unquote (quoted, quoted_len, buf);
     68 
     69   if (res_len != unquoted_len)
     70   {
     71     ret1 = 1;
     72     fprintf (stderr,
     73              "'MHD_str_unquote ()' FAILED: Wrong result size:\n");
     74   }
     75   else if ((0 != unquoted_len) && (0 != memcmp (buf, unquoted, unquoted_len)))
     76   {
     77     ret1 = 1;
     78     fprintf (stderr,
     79              "'MHD_str_unquote ()' FAILED: Wrong result string:\n");
     80   }
     81   if (0 != ret1)
     82   {
     83     /* This does NOT print part of the string after binary zero */
     84     fprintf (stderr,
     85              "\tRESULT  : MHD_str_unquote('%.*s', %u, ->'%.*s') -> %u\n"
     86              "\tEXPECTED: MHD_str_unquote('%.*s', %u, ->'%.*s') -> %u\n",
     87              (int) quoted_len, quoted, (unsigned) quoted_len,
     88              (int) res_len, buf, (unsigned) res_len,
     89              (int) quoted_len, quoted, (unsigned) quoted_len,
     90              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
     91     fprintf (stderr,
     92              "The check is at line: %u\n\n", line_num);
     93   }
     94 
     95   /* Second check: MHD_str_equal_quoted_bin_n () */
     96   ret2 = 0;
     97   if (! MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len))
     98   {
     99     fprintf (stderr,
    100              "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n");
    101     /* This does NOT print part of the string after binary zero */
    102     fprintf (stderr,
    103              "\tRESULT  : MHD_str_equal_quoted_bin_n('%.*s', %u, "
    104              "'%.*s', %u) -> true\n"
    105              "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, "
    106              "'%.*s', %u) -> false\n",
    107              (int) quoted_len, quoted, (unsigned) quoted_len,
    108              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    109              (int) quoted_len, quoted, (unsigned) quoted_len,
    110              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    111     fprintf (stderr,
    112              "The check is at line: %u\n\n", line_num);
    113     ret2 = 1;
    114   }
    115 
    116   /* Third check: MHD_str_equal_caseless_quoted_bin_n () */
    117   ret3 = 0;
    118   if (! MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted,
    119                                              unquoted_len))
    120   {
    121     fprintf (stderr,
    122              "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n")
    123     ;
    124     /* This does NOT print part of the string after binary zero */
    125     fprintf (stderr,
    126              "\tRESULT  : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    127              "'%.*s', %u) -> true\n"
    128              "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    129              "'%.*s', %u) -> false\n",
    130              (int) quoted_len, quoted, (unsigned) quoted_len,
    131              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    132              (int) quoted_len, quoted, (unsigned) quoted_len,
    133              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    134     fprintf (stderr,
    135              "The check is at line: %u\n\n", line_num);
    136     ret3 = 1;
    137   }
    138 
    139   /* Fourth check: MHD_str_unquote () */
    140   ret4 = 0;
    141   memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */
    142   res_len = MHD_str_quote (unquoted, unquoted_len, buf, quoted_len);
    143   if (res_len != quoted_len)
    144   {
    145     ret4 = 1;
    146     fprintf (stderr,
    147              "'MHD_str_quote ()' FAILED: Wrong result size:\n");
    148   }
    149   else if ((0 != quoted_len) && (0 != memcmp (buf, quoted, quoted_len)))
    150   {
    151     ret4 = 1;
    152     fprintf (stderr,
    153              "'MHD_str_quote ()' FAILED: Wrong result string:\n");
    154   }
    155   if (0 != ret4)
    156   {
    157     /* This does NOT print part of the string after binary zero */
    158     fprintf (stderr,
    159              "\tRESULT  : MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n"
    160              "\tEXPECTED: MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n",
    161              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    162              (int) res_len, buf, (unsigned) quoted_len, (unsigned) res_len,
    163              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    164              (int) quoted_len, quoted, (unsigned) quoted_len,
    165              (unsigned) unquoted_len);
    166     fprintf (stderr,
    167              "The check is at line: %u\n\n", line_num);
    168   }
    169 
    170   return ret1 + ret2 + ret3 + ret4;
    171 }
    172 
    173 
    174 #define expect_result_unquote(q,u) \
    175     expect_result_unquote_n(q,MHD_STATICSTR_LEN_(q),\
    176                             u,MHD_STATICSTR_LEN_(u),__LINE__)
    177 
    178 
    179 static unsigned int
    180 check_match (void)
    181 {
    182   unsigned int r = 0; /**< The number of errors */
    183 
    184   r += expect_result_unquote ("", "");
    185   r += expect_result_unquote ("a", "a");
    186   r += expect_result_unquote ("abc", "abc");
    187   r += expect_result_unquote ("abcdef", "abcdef");
    188   r += expect_result_unquote ("a\0" "bc", "a\0" "bc");
    189   r += expect_result_unquote ("abc\\\"", "abc\"");
    190   r += expect_result_unquote ("\\\"", "\"");
    191   r += expect_result_unquote ("\\\"abc", "\"abc");
    192   r += expect_result_unquote ("abc\\\\", "abc\\");
    193   r += expect_result_unquote ("\\\\", "\\");
    194   r += expect_result_unquote ("\\\\abc", "\\abc");
    195   r += expect_result_unquote ("123\\\\\\\\\\\\\\\\", "123\\\\\\\\");
    196   r += expect_result_unquote ("\\\\\\\\\\\\\\\\", "\\\\\\\\");
    197   r += expect_result_unquote ("\\\\\\\\\\\\\\\\123", "\\\\\\\\123");
    198   r += expect_result_unquote ("\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"" \
    199                               "\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"", \
    200                               "\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"");
    201 
    202   return r;
    203 }
    204 
    205 
    206 /* return zero if succeed, non-zero otherwise */
    207 static unsigned int
    208 expect_result_quote_failed_n (const char *const unquoted,
    209                               const size_t unquoted_len,
    210                               const size_t buf_size,
    211                               const unsigned int line_num)
    212 {
    213   static char buf[TEST_STR_MAX_LEN];
    214   size_t res_len;
    215   unsigned int ret4;
    216 
    217   mhd_assert (TEST_STR_MAX_LEN > buf_size);
    218 
    219   /* The check: MHD_str_unquote () */
    220   ret4 = 0;
    221   memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */
    222   res_len = MHD_str_quote (unquoted, unquoted_len, buf, buf_size);
    223   if (0 != res_len)
    224   {
    225     ret4 = 1;
    226     fprintf (stderr,
    227              "'MHD_str_quote ()' FAILED: Wrong result size:\n");
    228   }
    229   if (0 != ret4)
    230   {
    231     /* This does NOT print part of the string after binary zero */
    232     fprintf (stderr,
    233              "\tRESULT  : MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n"
    234              "\tEXPECTED: MHD_str_quote('%.*s', %u, (not checked), %u) -> 0\n",
    235              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    236              (int) res_len, buf,
    237              (unsigned) buf_size, (unsigned) res_len,
    238              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    239              (unsigned) buf_size);
    240     fprintf (stderr,
    241              "The check is at line: %u\n\n", line_num);
    242   }
    243 
    244   return ret4;
    245 }
    246 
    247 
    248 #define expect_result_quote_failed(q,s) \
    249     expect_result_quote_failed_n(q,MHD_STATICSTR_LEN_(q),\
    250                             s,__LINE__)
    251 
    252 
    253 static unsigned int
    254 check_quote_failed (void)
    255 {
    256   unsigned int r = 0; /**< The number of errors */
    257 
    258   r += expect_result_quote_failed ("a", 0);
    259   r += expect_result_quote_failed ("aa", 1);
    260   r += expect_result_quote_failed ("abc\\", 4);
    261   r += expect_result_quote_failed ("abc\"", 4);
    262   r += expect_result_quote_failed ("abc\"\"\"\"", 6);
    263   r += expect_result_quote_failed ("abc\"\"\"\"", 7);
    264   r += expect_result_quote_failed ("abc\"\"\"\"", 8);
    265   r += expect_result_quote_failed ("abc\"\"\"\"", 9);
    266   r += expect_result_quote_failed ("abc\"\"\"\"", 10);
    267   r += expect_result_quote_failed ("abc\\\\\\\\", 9);
    268   r += expect_result_quote_failed ("abc\\\\\\\\", 10);
    269   r += expect_result_quote_failed ("abc\"\"\"\"", 9);
    270   r += expect_result_quote_failed ("abc\"\"\"\"", 10);
    271   r += expect_result_quote_failed ("abc\"\\\"\\", 9);
    272   r += expect_result_quote_failed ("abc\\\"\\\"", 10);
    273   r += expect_result_quote_failed ("\"\"\"\"abc", 6);
    274   r += expect_result_quote_failed ("\"\"\"\"abc", 7);
    275   r += expect_result_quote_failed ("\"\"\"\"abc", 8);
    276   r += expect_result_quote_failed ("\"\"\"\"abc", 9);
    277   r += expect_result_quote_failed ("\"\"\"\"abc", 10);
    278   r += expect_result_quote_failed ("\\\\\\\\abc", 9);
    279   r += expect_result_quote_failed ("\\\\\\\\abc", 10);
    280   r += expect_result_quote_failed ("\"\"\"\"abc", 9);
    281   r += expect_result_quote_failed ("\"\"\"\"abc", 10);
    282   r += expect_result_quote_failed ("\"\\\"\\abc", 9);
    283   r += expect_result_quote_failed ("\\\"\\\"abc", 10);
    284 
    285   return r;
    286 }
    287 
    288 
    289 /* return zero if succeed, one otherwise */
    290 static unsigned int
    291 expect_match_caseless_n (const char *const quoted, const size_t quoted_len,
    292                          const char *const unquoted, const size_t unquoted_len,
    293                          const unsigned int line_num)
    294 {
    295   unsigned int ret3;
    296 
    297   mhd_assert (NULL != quoted);
    298   mhd_assert (NULL != unquoted);
    299   mhd_assert (TEST_STR_MAX_LEN > quoted_len);
    300 
    301   /* The check: MHD_str_equal_caseless_quoted_bin_n () */
    302   ret3 = 0;
    303   if (! MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted,
    304                                              unquoted_len))
    305   {
    306     fprintf (stderr,
    307              "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n")
    308     ;
    309     /* This does NOT print part of the string after binary zero */
    310     fprintf (stderr,
    311              "\tRESULT  : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    312              "'%.*s', %u) -> true\n"
    313              "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    314              "'%.*s', %u) -> false\n",
    315              (int) quoted_len, quoted, (unsigned) quoted_len,
    316              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    317              (int) quoted_len, quoted, (unsigned) quoted_len,
    318              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    319     fprintf (stderr,
    320              "The check is at line: %u\n\n", line_num);
    321     ret3 = 1;
    322   }
    323 
    324   return ret3;
    325 }
    326 
    327 
    328 #define expect_match_caseless(q,u) \
    329     expect_match_caseless_n(q,MHD_STATICSTR_LEN_(q),\
    330                             u,MHD_STATICSTR_LEN_(u),__LINE__)
    331 
    332 static unsigned int
    333 check_match_caseless (void)
    334 {
    335   unsigned int r = 0; /**< The number of errors */
    336 
    337   r += expect_match_caseless ("a", "A");
    338   r += expect_match_caseless ("abC", "aBc");
    339   r += expect_match_caseless ("AbCdeF", "aBCdEF");
    340   r += expect_match_caseless ("a\0" "Bc", "a\0" "bC");
    341   r += expect_match_caseless ("Abc\\\"", "abC\"");
    342   r += expect_match_caseless ("\\\"", "\"");
    343   r += expect_match_caseless ("\\\"aBc", "\"abc");
    344   r += expect_match_caseless ("abc\\\\", "ABC\\");
    345   r += expect_match_caseless ("\\\\", "\\");
    346   r += expect_match_caseless ("\\\\ABC", "\\abc");
    347   r += expect_match_caseless ("\\\\ZYX", "\\ZYX");
    348   r += expect_match_caseless ("abc", "ABC");
    349   r += expect_match_caseless ("ABCabc", "abcABC");
    350   r += expect_match_caseless ("abcXYZ", "ABCxyz");
    351   r += expect_match_caseless ("AbCdEfABCabc", "ABcdEFabcABC");
    352   r += expect_match_caseless ("a\\\\bc", "A\\BC");
    353   r += expect_match_caseless ("ABCa\\\\bc", "abcA\\BC");
    354   r += expect_match_caseless ("abcXYZ\\\\", "ABCxyz\\");
    355   r += expect_match_caseless ("\\\\AbCdEfABCabc", "\\ABcdEFabcABC");
    356 
    357   return r;
    358 }
    359 
    360 
    361 /* return zero if succeed, one otherwise */
    362 static unsigned int
    363 expect_result_invalid_n (const char *const quoted, const size_t quoted_len,
    364                          const unsigned int line_num)
    365 {
    366   static char buf[TEST_STR_MAX_LEN];
    367   size_t res_len;
    368   unsigned int ret1;
    369 
    370   mhd_assert (NULL != quoted);
    371   mhd_assert (TEST_STR_MAX_LEN > quoted_len);
    372 
    373   /* The check: MHD_str_unquote () */
    374   ret1 = 0;
    375   memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */
    376   res_len = MHD_str_unquote (quoted, quoted_len, buf);
    377 
    378   if (res_len != 0)
    379   {
    380     ret1 = 1;
    381     fprintf (stderr,
    382              "'MHD_str_unquote ()' FAILED: Wrong result size:\n");
    383   }
    384   if (0 != ret1)
    385   {
    386     /* This does NOT print part of the string after binary zero */
    387     fprintf (stderr,
    388              "\tRESULT  : MHD_str_unquote('%.*s', %u, (not checked)) -> %u\n"
    389              "\tEXPECTED: MHD_str_unquote('%.*s', %u, (not checked)) -> 0\n",
    390              (int) quoted_len, quoted, (unsigned) quoted_len,
    391              (unsigned) res_len,
    392              (int) quoted_len, quoted, (unsigned) quoted_len);
    393     fprintf (stderr,
    394              "The check is at line: %u\n\n", line_num);
    395   }
    396 
    397   return ret1;
    398 }
    399 
    400 
    401 #define expect_result_invalid(q) \
    402     expect_result_invalid_n(q,MHD_STATICSTR_LEN_(q),__LINE__)
    403 
    404 
    405 static unsigned int
    406 check_invalid (void)
    407 {
    408   unsigned int r = 0; /**< The number of errors */
    409 
    410   r += expect_result_invalid ("\\");
    411   r += expect_result_invalid ("\\\\\\");
    412   r += expect_result_invalid ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\");
    413   r += expect_result_invalid ("xyz\\");
    414   r += expect_result_invalid ("\\\"\\");
    415   r += expect_result_invalid ("\\\"\\\"\\\"\\");
    416 
    417   return r;
    418 }
    419 
    420 
    421 /* return zero if succeed, non-zero otherwise */
    422 static unsigned int
    423 expect_result_unmatch_n (const char *const quoted, const size_t quoted_len,
    424                          const char *const unquoted,
    425                          const size_t unquoted_len,
    426                          const unsigned int line_num)
    427 {
    428   unsigned int ret2;
    429   unsigned int ret3;
    430 
    431   mhd_assert (NULL != quoted);
    432   mhd_assert (NULL != unquoted);
    433 
    434   /* The check: MHD_str_equal_quoted_bin_n () */
    435   ret2 = 0;
    436   if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len))
    437   {
    438     fprintf (stderr,
    439              "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n");
    440     /* This does NOT print part of the string after binary zero */
    441     fprintf (stderr,
    442              "\tRESULT  : MHD_str_equal_quoted_bin_n('%.*s', %u, "
    443              "'%.*s', %u) -> true\n"
    444              "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, "
    445              "'%.*s', %u) -> false\n",
    446              (int) quoted_len, quoted, (unsigned) quoted_len,
    447              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    448              (int) quoted_len, quoted, (unsigned) quoted_len,
    449              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    450     fprintf (stderr,
    451              "The check is at line: %u\n\n", line_num);
    452     ret2 = 1;
    453   }
    454 
    455   /* The check: MHD_str_equal_quoted_bin_n () */
    456   ret3 = 0;
    457   if (MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted,
    458                                            unquoted_len))
    459   {
    460     fprintf (stderr,
    461              "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n")
    462     ;
    463     /* This does NOT print part of the string after binary zero */
    464     fprintf (stderr,
    465              "\tRESULT  : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    466              "'%.*s', %u) -> true\n"
    467              "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    468              "'%.*s', %u) -> false\n",
    469              (int) quoted_len, quoted, (unsigned) quoted_len,
    470              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    471              (int) quoted_len, quoted, (unsigned) quoted_len,
    472              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    473     fprintf (stderr,
    474              "The check is at line: %u\n\n", line_num);
    475     ret3 = 1;
    476   }
    477 
    478   return ret2 + ret3;
    479 }
    480 
    481 
    482 #define expect_result_unmatch(q,u) \
    483     expect_result_unmatch_n(q,MHD_STATICSTR_LEN_(q),\
    484                             u,MHD_STATICSTR_LEN_(u),__LINE__)
    485 
    486 
    487 static unsigned int
    488 check_unmatch (void)
    489 {
    490   unsigned int r = 0; /**< The number of errors */
    491 
    492   /* Matched sequence except invalid backslash at the end */
    493   r += expect_result_unmatch ("\\", "");
    494   r += expect_result_unmatch ("a\\", "a");
    495   r += expect_result_unmatch ("abc\\", "abc");
    496   r += expect_result_unmatch ("a\0" "bc\\", "a\0" "bc");
    497   r += expect_result_unmatch ("abc\\\"\\", "abc\"");
    498   r += expect_result_unmatch ("\\\"\\", "\"");
    499   r += expect_result_unmatch ("\\\"abc\\", "\"abc");
    500   r += expect_result_unmatch ("abc\\\\\\", "abc\\");
    501   r += expect_result_unmatch ("\\\\\\", "\\");
    502   r += expect_result_unmatch ("\\\\abc\\", "\\abc");
    503   r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\", "123\\\\\\\\");
    504   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\", "\\\\\\\\");
    505   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\", "\\\\\\\\123");
    506   /* Invalid backslash at the end and empty string */
    507   r += expect_result_unmatch ("\\", "");
    508   r += expect_result_unmatch ("a\\", "");
    509   r += expect_result_unmatch ("abc\\", "");
    510   r += expect_result_unmatch ("a\0" "bc\\", "");
    511   r += expect_result_unmatch ("abc\\\"\\", "");
    512   r += expect_result_unmatch ("\\\"\\", "");
    513   r += expect_result_unmatch ("\\\"abc\\", "");
    514   r += expect_result_unmatch ("abc\\\\\\", "");
    515   r += expect_result_unmatch ("\\\\\\", "");
    516   r += expect_result_unmatch ("\\\\abc\\", "");
    517   r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\", "");
    518   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\", "");
    519   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\", "");
    520   /* Difference at binary zero */
    521   r += expect_result_unmatch ("\0", "");
    522   r += expect_result_unmatch ("", "\0");
    523   r += expect_result_unmatch ("a\0", "a");
    524   r += expect_result_unmatch ("a", "a\0");
    525   r += expect_result_unmatch ("abc\0", "abc");
    526   r += expect_result_unmatch ("abc", "abc\0");
    527   r += expect_result_unmatch ("a\0" "bc\0", "a\0" "bc");
    528   r += expect_result_unmatch ("a\0" "bc", "a\0" "bc\0");
    529   r += expect_result_unmatch ("abc\\\"\0", "abc\"");
    530   r += expect_result_unmatch ("abc\\\"", "abc\"\0");
    531   r += expect_result_unmatch ("\\\"\0", "\"");
    532   r += expect_result_unmatch ("\\\"", "\"\0");
    533   r += expect_result_unmatch ("\\\"abc\0", "\"abc");
    534   r += expect_result_unmatch ("\\\"abc", "\"abc\0");
    535   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\0", "\\\\\\\\");
    536   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\0");
    537   r += expect_result_unmatch ("\\\\\\\\\\\\\0" "\\\\", "\\\\\\\\");
    538   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\0" "\\");
    539   r += expect_result_unmatch ("\0" "abc", "abc");
    540   r += expect_result_unmatch ("abc", "\0" "abc");
    541   r += expect_result_unmatch ("\0" "abc", "0abc");
    542   r += expect_result_unmatch ("0abc", "\0" "abc");
    543   r += expect_result_unmatch ("xyz", "xy" "\0" "z");
    544   r += expect_result_unmatch ("xy" "\0" "z", "xyz");
    545   /* Difference after binary zero */
    546   r += expect_result_unmatch ("abc\0" "1", "abc\0" "2");
    547   r += expect_result_unmatch ("a\0" "bcx", "a\0" "bcy");
    548   r += expect_result_unmatch ("\0" "abc\\\"2", "\0" "abc\"1");
    549   r += expect_result_unmatch ("\0" "abc1\\\"", "\0" "abc2\"");
    550   r += expect_result_unmatch ("\0" "\\\"c", "\0" "\"d");
    551   r += expect_result_unmatch ("\\\"ab" "\0" "1c", "\"ab" "\0" "2c");
    552   r += expect_result_unmatch ("a\0" "bcdef2", "a\0" "bcdef1");
    553   r += expect_result_unmatch ("a\0" "bc2def", "a\0" "bc1def");
    554   r += expect_result_unmatch ("a\0" "1bcdef", "a\0" "2bcdef");
    555   r += expect_result_unmatch ("abcde\0" "f2", "abcde\0" "f1");
    556   r += expect_result_unmatch ("123\\\\\\\\\\\\\0" "\\\\1", "123\\\\\\\0" "\\2");
    557   r += expect_result_unmatch ("\\\\\\\\\\\\\0" "1\\\\", "\\\\\\" "2\\");
    558   /* One side is empty */
    559   r += expect_result_unmatch ("abc", "");
    560   r += expect_result_unmatch ("", "abc");
    561   r += expect_result_unmatch ("1234567890", "");
    562   r += expect_result_unmatch ("", "1234567890");
    563   r += expect_result_unmatch ("abc\\\"", "");
    564   r += expect_result_unmatch ("", "abc\"");
    565   r += expect_result_unmatch ("\\\"", "");
    566   r += expect_result_unmatch ("", "\"");
    567   r += expect_result_unmatch ("\\\"abc", "");
    568   r += expect_result_unmatch ("", "\"abc");
    569   r += expect_result_unmatch ("abc\\\\", "");
    570   r += expect_result_unmatch ("", "abc\\");
    571   r += expect_result_unmatch ("\\\\", "");
    572   r += expect_result_unmatch ("", "\\");
    573   r += expect_result_unmatch ("\\\\abc", "");
    574   r += expect_result_unmatch ("", "\\abc");
    575   r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\", "");
    576   r += expect_result_unmatch ("", "123\\\\\\\\");
    577   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "");
    578   r += expect_result_unmatch ("", "\\\\\\\\");
    579   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123", "");
    580   r += expect_result_unmatch ("", "\\\\\\\\123");
    581   /* Various unmatched strings */
    582   r += expect_result_unmatch ("a", "x");
    583   r += expect_result_unmatch ("abc", "abcabc");
    584   r += expect_result_unmatch ("abc", "abcabcabc");
    585   r += expect_result_unmatch ("abc", "abcabcabcabc");
    586   r += expect_result_unmatch ("ABCABC", "ABC");
    587   r += expect_result_unmatch ("ABCABCABC", "ABC");
    588   r += expect_result_unmatch ("ABCABCABCABC", "ABC");
    589   r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\\\", "123\\\\\\\\");
    590   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\\\", "\\\\\\\\");
    591   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\\\", "\\\\\\\\123");
    592   r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\\");
    593 
    594   return r;
    595 }
    596 
    597 
    598 /* return zero if succeed, one otherwise */
    599 static unsigned int
    600 expect_result_case_unmatch_n (const char *const quoted,
    601                               const size_t quoted_len,
    602                               const char *const unquoted,
    603                               const size_t unquoted_len,
    604                               const unsigned int line_num)
    605 {
    606   unsigned int ret2;
    607 
    608   mhd_assert (NULL != quoted);
    609   mhd_assert (NULL != unquoted);
    610 
    611   /* THe check: MHD_str_equal_quoted_bin_n () */
    612   ret2 = 0;
    613   if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len))
    614   {
    615     fprintf (stderr,
    616              "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n");
    617     /* This does NOT print part of the string after binary zero */
    618     fprintf (stderr,
    619              "\tRESULT  : MHD_str_equal_quoted_bin_n('%.*s', %u, "
    620              "'%.*s', %u) -> true\n"
    621              "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, "
    622              "'%.*s', %u) -> false\n",
    623              (int) quoted_len, quoted, (unsigned) quoted_len,
    624              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    625              (int) quoted_len, quoted, (unsigned) quoted_len,
    626              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    627     fprintf (stderr,
    628              "The check is at line: %u\n\n", line_num);
    629     ret2 = 1;
    630   }
    631 
    632   return ret2;
    633 }
    634 
    635 
    636 #define expect_result_case_unmatch(q,u) \
    637     expect_result_case_unmatch_n(q,MHD_STATICSTR_LEN_(q),\
    638                                  u,MHD_STATICSTR_LEN_(u),__LINE__)
    639 
    640 static unsigned int
    641 check_unmatch_case (void)
    642 {
    643   unsigned int r = 0; /**< The number of errors */
    644 
    645   r += expect_result_case_unmatch ("a", "A");
    646   r += expect_result_case_unmatch ("abC", "aBc");
    647   r += expect_result_case_unmatch ("AbCdeF", "aBCdEF");
    648   r += expect_result_case_unmatch ("a\0" "Bc", "a\0" "bC");
    649   r += expect_result_case_unmatch ("Abc\\\"", "abC\"");
    650   r += expect_result_case_unmatch ("\\\"aBc", "\"abc");
    651   r += expect_result_case_unmatch ("abc\\\\", "ABC\\");
    652   r += expect_result_case_unmatch ("\\\\ABC", "\\abc");
    653   r += expect_result_case_unmatch ("\\\\ZYX", "\\ZYx");
    654   r += expect_result_case_unmatch ("abc", "ABC");
    655   r += expect_result_case_unmatch ("ABCabc", "abcABC");
    656   r += expect_result_case_unmatch ("abcXYZ", "ABCxyz");
    657   r += expect_result_case_unmatch ("AbCdEfABCabc", "ABcdEFabcABC");
    658   r += expect_result_case_unmatch ("a\\\\bc", "A\\BC");
    659   r += expect_result_case_unmatch ("ABCa\\\\bc", "abcA\\BC");
    660   r += expect_result_case_unmatch ("abcXYZ\\\\", "ABCxyz\\");
    661   r += expect_result_case_unmatch ("\\\\AbCdEfABCabc", "\\ABcdEFabcABC");
    662 
    663   return r;
    664 }
    665 
    666 
    667 /* return zero if succeed, one otherwise */
    668 static unsigned int
    669 expect_result_caseless_unmatch_n (const char *const quoted,
    670                                   const size_t quoted_len,
    671                                   const char *const unquoted,
    672                                   const size_t unquoted_len,
    673                                   const unsigned int line_num)
    674 {
    675   unsigned int ret2;
    676   unsigned int ret3;
    677 
    678   mhd_assert (NULL != quoted);
    679   mhd_assert (NULL != unquoted);
    680 
    681   /* The check: MHD_str_equal_quoted_bin_n () */
    682   ret2 = 0;
    683   if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len))
    684   {
    685     fprintf (stderr,
    686              "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n");
    687     /* This does NOT print part of the string after binary zero */
    688     fprintf (stderr,
    689              "\tRESULT  : MHD_str_equal_quoted_bin_n('%.*s', %u, "
    690              "'%.*s', %u) -> true\n"
    691              "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, "
    692              "'%.*s', %u) -> false\n",
    693              (int) quoted_len, quoted, (unsigned) quoted_len,
    694              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    695              (int) quoted_len, quoted, (unsigned) quoted_len,
    696              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    697     fprintf (stderr,
    698              "The check is at line: %u\n\n", line_num);
    699     ret2 = 1;
    700   }
    701 
    702   /* The check: MHD_str_equal_quoted_bin_n () */
    703   ret3 = 0;
    704   if (MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted,
    705                                            unquoted_len))
    706   {
    707     fprintf (stderr,
    708              "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n")
    709     ;
    710     /* This does NOT print part of the string after binary zero */
    711     fprintf (stderr,
    712              "\tRESULT  : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    713              "'%.*s', %u) -> true\n"
    714              "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, "
    715              "'%.*s', %u) -> false\n",
    716              (int) quoted_len, quoted, (unsigned) quoted_len,
    717              (int) unquoted_len, unquoted, (unsigned) unquoted_len,
    718              (int) quoted_len, quoted, (unsigned) quoted_len,
    719              (int) unquoted_len, unquoted, (unsigned) unquoted_len);
    720     fprintf (stderr,
    721              "The check is at line: %u\n\n", line_num);
    722     ret3 = 1;
    723   }
    724 
    725   return ret2 + ret3;
    726 }
    727 
    728 
    729 #define expect_result_caseless_unmatch(q,u) \
    730     expect_result_caseless_unmatch_n(q,MHD_STATICSTR_LEN_(q),\
    731                                      u,MHD_STATICSTR_LEN_(u),__LINE__)
    732 
    733 
    734 static unsigned int
    735 check_unmatch_caseless (void)
    736 {
    737   unsigned int r = 0; /**< The number of errors */
    738 
    739   /* Matched sequence except invalid backslash at the end */
    740   r += expect_result_caseless_unmatch ("a\\", "A");
    741   r += expect_result_caseless_unmatch ("abC\\", "abc");
    742   r += expect_result_caseless_unmatch ("a\0" "Bc\\", "a\0" "bc");
    743   r += expect_result_caseless_unmatch ("abc\\\"\\", "ABC\"");
    744   r += expect_result_caseless_unmatch ("\\\"\\", "\"");
    745   r += expect_result_caseless_unmatch ("\\\"ABC\\", "\"abc");
    746   r += expect_result_caseless_unmatch ("Abc\\\\\\", "abC\\");
    747   r += expect_result_caseless_unmatch ("\\\\\\", "\\");
    748   r += expect_result_caseless_unmatch ("\\\\aBc\\", "\\abC");
    749   /* Difference at binary zero */
    750   r += expect_result_caseless_unmatch ("a\0", "A");
    751   r += expect_result_caseless_unmatch ("A", "a\0");
    752   r += expect_result_caseless_unmatch ("abC\0", "abc");
    753   r += expect_result_caseless_unmatch ("abc", "ABc\0");
    754   r += expect_result_caseless_unmatch ("a\0" "bC\0", "a\0" "bc");
    755   r += expect_result_caseless_unmatch ("a\0" "bc", "A\0" "bc\0");
    756   r += expect_result_caseless_unmatch ("ABC\\\"\0", "abc\"");
    757   r += expect_result_caseless_unmatch ("abc\\\"", "ABC\"\0");
    758   r += expect_result_caseless_unmatch ("\\\"aBc\0", "\"abc");
    759   r += expect_result_caseless_unmatch ("\\\"Abc", "\"abc\0");
    760   r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\\0", "\\\\\\\\");
    761   r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\0");
    762   r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\0" "\\\\", "\\\\\\\\");
    763   r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\0" "\\");
    764   r += expect_result_caseless_unmatch ("\0" "aBc", "abc");
    765   r += expect_result_caseless_unmatch ("abc", "\0" "abC");
    766   r += expect_result_caseless_unmatch ("\0" "abc", "0abc");
    767   r += expect_result_caseless_unmatch ("0abc", "\0" "aBc");
    768   r += expect_result_caseless_unmatch ("xyZ", "xy" "\0" "z");
    769   r += expect_result_caseless_unmatch ("Xy" "\0" "z", "xyz");
    770   /* Difference after binary zero */
    771   r += expect_result_caseless_unmatch ("abc\0" "1", "aBC\0" "2");
    772   r += expect_result_caseless_unmatch ("a\0" "bcX", "a\0" "bcy");
    773   r += expect_result_caseless_unmatch ("\0" "abc\\\"2", "\0" "Abc\"1");
    774   r += expect_result_caseless_unmatch ("\0" "Abc1\\\"", "\0" "abc2\"");
    775   r += expect_result_caseless_unmatch ("\0" "\\\"c", "\0" "\"d");
    776   r += expect_result_caseless_unmatch ("\\\"ab" "\0" "1C", "\"ab" "\0" "2C");
    777   r += expect_result_caseless_unmatch ("a\0" "BCDef2", "a\0" "bcdef1");
    778   r += expect_result_caseless_unmatch ("a\0" "bc2def", "a\0" "BC1def");
    779   r += expect_result_caseless_unmatch ("a\0" "1bcdeF", "a\0" "2bcdef");
    780   r += expect_result_caseless_unmatch ("abcde\0" "f2", "ABCDE\0" "f1");
    781   r += expect_result_caseless_unmatch ("\\\"ab" "\0" "XC", "\"ab" "\0" "yC");
    782   r += expect_result_caseless_unmatch ("a\0" "BCDefY", "a\0" "bcdefx");
    783   r += expect_result_caseless_unmatch ("a\0" "bczdef", "a\0" "BCXdef");
    784   r += expect_result_caseless_unmatch ("a\0" "YbcdeF", "a\0" "zbcdef");
    785   r += expect_result_caseless_unmatch ("abcde\0" "fy", "ABCDE\0" "fX");
    786 
    787   return r;
    788 }
    789 
    790 
    791 int
    792 main (int argc, char *argv[])
    793 {
    794   unsigned int errcount = 0;
    795   (void) argc; (void) argv; /* Unused. Silent compiler warning. */
    796   errcount += check_match ();
    797   errcount += check_quote_failed ();
    798   errcount += check_match_caseless ();
    799   errcount += check_invalid ();
    800   errcount += check_unmatch ();
    801   errcount += check_unmatch_case ();
    802   errcount += check_unmatch_caseless ();
    803   if (0 == errcount)
    804     printf ("All tests were passed without errors.\n");
    805   return errcount == 0 ? 0 : 1;
    806 }