libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

unit_str_quote.c (31726B)


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