libmicrohttpd2

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

test_str_quote.c (31334B)


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