| /* |
| This file is part of libmicrohttpd |
| Copyright (C) 2022 Karlson2k (Evgeny Grin) |
| |
| This test tool is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License as |
| published by the Free Software Foundation; either version 2, or |
| (at your option) any later version. |
| |
| This test tool is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU Lesser General Public |
| License along with this library; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| /** |
| * @file microhttpd/test_str_quote.c |
| * @brief Unit tests for quoted strings processing |
| * @author Karlson2k (Evgeny Grin) |
| */ |
| |
| #include "mhd_options.h" |
| #include <string.h> |
| #include <stdio.h> |
| #include "mhd_str.h" |
| #include "mhd_assert.h" |
| |
| #ifndef MHD_STATICSTR_LEN_ |
| /** |
| * Determine length of static string / macro strings at compile time. |
| */ |
| #define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1) |
| #endif /* ! MHD_STATICSTR_LEN_ */ |
| |
| |
| #define TEST_STR_MAX_LEN 1024 |
| |
| /* return zero if succeed, non-zero otherwise */ |
| static unsigned int |
| expect_result_unquote_n (const char *const quoted, const size_t quoted_len, |
| const char *const unquoted, const size_t unquoted_len, |
| const unsigned int line_num) |
| { |
| static char buf[TEST_STR_MAX_LEN]; |
| size_t res_len; |
| unsigned int ret1; |
| unsigned int ret2; |
| unsigned int ret3; |
| unsigned int ret4; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (NULL != unquoted); |
| mhd_assert (TEST_STR_MAX_LEN > quoted_len); |
| mhd_assert (quoted_len >= unquoted_len); |
| |
| /* First check: MHD_str_unquote () */ |
| ret1 = 0; |
| memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */ |
| res_len = MHD_str_unquote (quoted, quoted_len, buf); |
| |
| if (res_len != unquoted_len) |
| { |
| ret1 = 1; |
| fprintf (stderr, |
| "'MHD_str_unquote ()' FAILED: Wrong result size:\n"); |
| } |
| else if ((0 != unquoted_len) && (0 != memcmp (buf, unquoted, unquoted_len))) |
| { |
| ret1 = 1; |
| fprintf (stderr, |
| "'MHD_str_unquote ()' FAILED: Wrong result string:\n"); |
| } |
| if (0 != ret1) |
| { |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_unquote('%.*s', %u, ->'%.*s') -> %u\n" |
| "\tEXPECTED: MHD_str_unquote('%.*s', %u, ->'%.*s') -> %u\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) res_len, buf, (unsigned) res_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| } |
| |
| /* Second check: MHD_str_equal_quoted_bin_n () */ |
| ret2 = 0; |
| if (! MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret2 = 1; |
| } |
| |
| /* Third check: MHD_str_equal_caseless_quoted_bin_n () */ |
| ret3 = 0; |
| if (! MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted, |
| unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret3 = 1; |
| } |
| |
| /* Fourth check: MHD_str_unquote () */ |
| ret4 = 0; |
| memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */ |
| res_len = MHD_str_quote (unquoted, unquoted_len, buf, quoted_len); |
| if (res_len != quoted_len) |
| { |
| ret4 = 1; |
| fprintf (stderr, |
| "'MHD_str_quote ()' FAILED: Wrong result size:\n"); |
| } |
| else if ((0 != quoted_len) && (0 != memcmp (buf, quoted, quoted_len))) |
| { |
| ret4 = 1; |
| fprintf (stderr, |
| "'MHD_str_quote ()' FAILED: Wrong result string:\n"); |
| } |
| if (0 != ret4) |
| { |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n" |
| "\tEXPECTED: MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n", |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) res_len, buf, (unsigned) quoted_len, (unsigned) res_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| } |
| |
| return ret1 + ret2 + ret3 + ret4; |
| } |
| |
| |
| #define expect_result_unquote(q,u) \ |
| expect_result_unquote_n(q,MHD_STATICSTR_LEN_(q),\ |
| u,MHD_STATICSTR_LEN_(u),__LINE__) |
| |
| |
| static unsigned int |
| check_match (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| r += expect_result_unquote ("", ""); |
| r += expect_result_unquote ("a", "a"); |
| r += expect_result_unquote ("abc", "abc"); |
| r += expect_result_unquote ("abcdef", "abcdef"); |
| r += expect_result_unquote ("a\0" "bc", "a\0" "bc"); |
| r += expect_result_unquote ("abc\\\"", "abc\""); |
| r += expect_result_unquote ("\\\"", "\""); |
| r += expect_result_unquote ("\\\"abc", "\"abc"); |
| r += expect_result_unquote ("abc\\\\", "abc\\"); |
| r += expect_result_unquote ("\\\\", "\\"); |
| r += expect_result_unquote ("\\\\abc", "\\abc"); |
| r += expect_result_unquote ("123\\\\\\\\\\\\\\\\", "123\\\\\\\\"); |
| r += expect_result_unquote ("\\\\\\\\\\\\\\\\", "\\\\\\\\"); |
| r += expect_result_unquote ("\\\\\\\\\\\\\\\\123", "\\\\\\\\123"); |
| r += expect_result_unquote ("\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"" \ |
| "\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"\\\\\\\"", \ |
| "\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\"\\\""); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, non-zero otherwise */ |
| static unsigned int |
| expect_result_quote_failed_n (const char *const unquoted, |
| const size_t unquoted_len, |
| const size_t buf_size, |
| const unsigned int line_num) |
| { |
| static char buf[TEST_STR_MAX_LEN]; |
| size_t res_len; |
| unsigned int ret4; |
| |
| mhd_assert (TEST_STR_MAX_LEN > buf_size); |
| |
| /* The check: MHD_str_unquote () */ |
| ret4 = 0; |
| memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */ |
| res_len = MHD_str_quote (unquoted, unquoted_len, buf, buf_size); |
| if (0 != res_len) |
| { |
| ret4 = 1; |
| fprintf (stderr, |
| "'MHD_str_quote ()' FAILED: Wrong result size:\n"); |
| } |
| if (0 != ret4) |
| { |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_quote('%.*s', %u, ->'%.*s', %u) -> %u\n" |
| "\tEXPECTED: MHD_str_quote('%.*s', %u, (not checked), %u) -> 0\n", |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) res_len, buf, |
| (unsigned) buf_size, (unsigned) res_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (unsigned) buf_size); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| } |
| |
| return ret4; |
| } |
| |
| |
| #define expect_result_quote_failed(q,s) \ |
| expect_result_quote_failed_n(q,MHD_STATICSTR_LEN_(q),\ |
| s,__LINE__) |
| |
| |
| static unsigned int |
| check_quote_failed (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| r += expect_result_quote_failed ("a", 0); |
| r += expect_result_quote_failed ("aa", 1); |
| r += expect_result_quote_failed ("abc\\", 4); |
| r += expect_result_quote_failed ("abc\"", 4); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 6); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 7); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 8); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 9); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 10); |
| r += expect_result_quote_failed ("abc\\\\\\\\", 9); |
| r += expect_result_quote_failed ("abc\\\\\\\\", 10); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 9); |
| r += expect_result_quote_failed ("abc\"\"\"\"", 10); |
| r += expect_result_quote_failed ("abc\"\\\"\\", 9); |
| r += expect_result_quote_failed ("abc\\\"\\\"", 10); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 6); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 7); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 8); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 9); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 10); |
| r += expect_result_quote_failed ("\\\\\\\\abc", 9); |
| r += expect_result_quote_failed ("\\\\\\\\abc", 10); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 9); |
| r += expect_result_quote_failed ("\"\"\"\"abc", 10); |
| r += expect_result_quote_failed ("\"\\\"\\abc", 9); |
| r += expect_result_quote_failed ("\\\"\\\"abc", 10); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, one otherwise */ |
| static unsigned int |
| expect_match_caseless_n (const char *const quoted, const size_t quoted_len, |
| const char *const unquoted, const size_t unquoted_len, |
| const unsigned int line_num) |
| { |
| unsigned int ret3; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (NULL != unquoted); |
| mhd_assert (TEST_STR_MAX_LEN > quoted_len); |
| |
| /* The check: MHD_str_equal_caseless_quoted_bin_n () */ |
| ret3 = 0; |
| if (! MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted, |
| unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret3 = 1; |
| } |
| |
| return ret3; |
| } |
| |
| |
| #define expect_match_caseless(q,u) \ |
| expect_match_caseless_n(q,MHD_STATICSTR_LEN_(q),\ |
| u,MHD_STATICSTR_LEN_(u),__LINE__) |
| |
| static unsigned int |
| check_match_caseless (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| r += expect_match_caseless ("a", "A"); |
| r += expect_match_caseless ("abC", "aBc"); |
| r += expect_match_caseless ("AbCdeF", "aBCdEF"); |
| r += expect_match_caseless ("a\0" "Bc", "a\0" "bC"); |
| r += expect_match_caseless ("Abc\\\"", "abC\""); |
| r += expect_match_caseless ("\\\"", "\""); |
| r += expect_match_caseless ("\\\"aBc", "\"abc"); |
| r += expect_match_caseless ("abc\\\\", "ABC\\"); |
| r += expect_match_caseless ("\\\\", "\\"); |
| r += expect_match_caseless ("\\\\ABC", "\\abc"); |
| r += expect_match_caseless ("\\\\ZYX", "\\ZYX"); |
| r += expect_match_caseless ("abc", "ABC"); |
| r += expect_match_caseless ("ABCabc", "abcABC"); |
| r += expect_match_caseless ("abcXYZ", "ABCxyz"); |
| r += expect_match_caseless ("AbCdEfABCabc", "ABcdEFabcABC"); |
| r += expect_match_caseless ("a\\\\bc", "A\\BC"); |
| r += expect_match_caseless ("ABCa\\\\bc", "abcA\\BC"); |
| r += expect_match_caseless ("abcXYZ\\\\", "ABCxyz\\"); |
| r += expect_match_caseless ("\\\\AbCdEfABCabc", "\\ABcdEFabcABC"); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, one otherwise */ |
| static unsigned int |
| expect_result_invalid_n (const char *const quoted, const size_t quoted_len, |
| const unsigned int line_num) |
| { |
| static char buf[TEST_STR_MAX_LEN]; |
| size_t res_len; |
| unsigned int ret1; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (TEST_STR_MAX_LEN > quoted_len); |
| |
| /* The check: MHD_str_unquote () */ |
| ret1 = 0; |
| memset (buf, '#', sizeof(buf)); /* Fill buffer with character unused in the check */ |
| res_len = MHD_str_unquote (quoted, quoted_len, buf); |
| |
| if (res_len != 0) |
| { |
| ret1 = 1; |
| fprintf (stderr, |
| "'MHD_str_unquote ()' FAILED: Wrong result size:\n"); |
| } |
| if (0 != ret1) |
| { |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_unquote('%.*s', %u, (not checked)) -> %u\n" |
| "\tEXPECTED: MHD_str_unquote('%.*s', %u, (not checked)) -> 0\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (unsigned) res_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| } |
| |
| return ret1; |
| } |
| |
| |
| #define expect_result_invalid(q) \ |
| expect_result_invalid_n(q,MHD_STATICSTR_LEN_(q),__LINE__) |
| |
| |
| static unsigned int |
| check_invalid (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| r += expect_result_invalid ("\\"); |
| r += expect_result_invalid ("\\\\\\"); |
| r += expect_result_invalid ("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"); |
| r += expect_result_invalid ("xyz\\"); |
| r += expect_result_invalid ("\\\"\\"); |
| r += expect_result_invalid ("\\\"\\\"\\\"\\"); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, non-zero otherwise */ |
| static unsigned int |
| expect_result_unmatch_n (const char *const quoted, const size_t quoted_len, |
| const char *const unquoted, |
| const size_t unquoted_len, |
| const unsigned int line_num) |
| { |
| unsigned int ret2; |
| unsigned int ret3; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (NULL != unquoted); |
| |
| /* The check: MHD_str_equal_quoted_bin_n () */ |
| ret2 = 0; |
| if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret2 = 1; |
| } |
| |
| /* The check: MHD_str_equal_quoted_bin_n () */ |
| ret3 = 0; |
| if (MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted, |
| unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret3 = 1; |
| } |
| |
| return ret2 + ret3; |
| } |
| |
| |
| #define expect_result_unmatch(q,u) \ |
| expect_result_unmatch_n(q,MHD_STATICSTR_LEN_(q),\ |
| u,MHD_STATICSTR_LEN_(u),__LINE__) |
| |
| |
| static unsigned int |
| check_unmatch (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| /* Matched sequence except invalid backslash at the end */ |
| r += expect_result_unmatch ("\\", ""); |
| r += expect_result_unmatch ("a\\", "a"); |
| r += expect_result_unmatch ("abc\\", "abc"); |
| r += expect_result_unmatch ("a\0" "bc\\", "a\0" "bc"); |
| r += expect_result_unmatch ("abc\\\"\\", "abc\""); |
| r += expect_result_unmatch ("\\\"\\", "\""); |
| r += expect_result_unmatch ("\\\"abc\\", "\"abc"); |
| r += expect_result_unmatch ("abc\\\\\\", "abc\\"); |
| r += expect_result_unmatch ("\\\\\\", "\\"); |
| r += expect_result_unmatch ("\\\\abc\\", "\\abc"); |
| r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\", "123\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\", "\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\", "\\\\\\\\123"); |
| /* Invalid backslash at the end and empty string */ |
| r += expect_result_unmatch ("\\", ""); |
| r += expect_result_unmatch ("a\\", ""); |
| r += expect_result_unmatch ("abc\\", ""); |
| r += expect_result_unmatch ("a\0" "bc\\", ""); |
| r += expect_result_unmatch ("abc\\\"\\", ""); |
| r += expect_result_unmatch ("\\\"\\", ""); |
| r += expect_result_unmatch ("\\\"abc\\", ""); |
| r += expect_result_unmatch ("abc\\\\\\", ""); |
| r += expect_result_unmatch ("\\\\\\", ""); |
| r += expect_result_unmatch ("\\\\abc\\", ""); |
| r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\", ""); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\", ""); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\", ""); |
| /* Difference at binary zero */ |
| r += expect_result_unmatch ("\0", ""); |
| r += expect_result_unmatch ("", "\0"); |
| r += expect_result_unmatch ("a\0", "a"); |
| r += expect_result_unmatch ("a", "a\0"); |
| r += expect_result_unmatch ("abc\0", "abc"); |
| r += expect_result_unmatch ("abc", "abc\0"); |
| r += expect_result_unmatch ("a\0" "bc\0", "a\0" "bc"); |
| r += expect_result_unmatch ("a\0" "bc", "a\0" "bc\0"); |
| r += expect_result_unmatch ("abc\\\"\0", "abc\""); |
| r += expect_result_unmatch ("abc\\\"", "abc\"\0"); |
| r += expect_result_unmatch ("\\\"\0", "\""); |
| r += expect_result_unmatch ("\\\"", "\"\0"); |
| r += expect_result_unmatch ("\\\"abc\0", "\"abc"); |
| r += expect_result_unmatch ("\\\"abc", "\"abc\0"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\0", "\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\0"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\0" "\\\\", "\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\0" "\\"); |
| r += expect_result_unmatch ("\0" "abc", "abc"); |
| r += expect_result_unmatch ("abc", "\0" "abc"); |
| r += expect_result_unmatch ("\0" "abc", "0abc"); |
| r += expect_result_unmatch ("0abc", "\0" "abc"); |
| r += expect_result_unmatch ("xyz", "xy" "\0" "z"); |
| r += expect_result_unmatch ("xy" "\0" "z", "xyz"); |
| /* Difference after binary zero */ |
| r += expect_result_unmatch ("abc\0" "1", "abc\0" "2"); |
| r += expect_result_unmatch ("a\0" "bcx", "a\0" "bcy"); |
| r += expect_result_unmatch ("\0" "abc\\\"2", "\0" "abc\"1"); |
| r += expect_result_unmatch ("\0" "abc1\\\"", "\0" "abc2\""); |
| r += expect_result_unmatch ("\0" "\\\"c", "\0" "\"d"); |
| r += expect_result_unmatch ("\\\"ab" "\0" "1c", "\"ab" "\0" "2c"); |
| r += expect_result_unmatch ("a\0" "bcdef2", "a\0" "bcdef1"); |
| r += expect_result_unmatch ("a\0" "bc2def", "a\0" "bc1def"); |
| r += expect_result_unmatch ("a\0" "1bcdef", "a\0" "2bcdef"); |
| r += expect_result_unmatch ("abcde\0" "f2", "abcde\0" "f1"); |
| r += expect_result_unmatch ("123\\\\\\\\\\\\\0" "\\\\1", "123\\\\\\\0" "\\2"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\0" "1\\\\", "\\\\\\" "2\\"); |
| /* One side is empty */ |
| r += expect_result_unmatch ("abc", ""); |
| r += expect_result_unmatch ("", "abc"); |
| r += expect_result_unmatch ("1234567890", ""); |
| r += expect_result_unmatch ("", "1234567890"); |
| r += expect_result_unmatch ("abc\\\"", ""); |
| r += expect_result_unmatch ("", "abc\""); |
| r += expect_result_unmatch ("\\\"", ""); |
| r += expect_result_unmatch ("", "\""); |
| r += expect_result_unmatch ("\\\"abc", ""); |
| r += expect_result_unmatch ("", "\"abc"); |
| r += expect_result_unmatch ("abc\\\\", ""); |
| r += expect_result_unmatch ("", "abc\\"); |
| r += expect_result_unmatch ("\\\\", ""); |
| r += expect_result_unmatch ("", "\\"); |
| r += expect_result_unmatch ("\\\\abc", ""); |
| r += expect_result_unmatch ("", "\\abc"); |
| r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\", ""); |
| r += expect_result_unmatch ("", "123\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", ""); |
| r += expect_result_unmatch ("", "\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123", ""); |
| r += expect_result_unmatch ("", "\\\\\\\\123"); |
| /* Various unmatched strings */ |
| r += expect_result_unmatch ("a", "x"); |
| r += expect_result_unmatch ("abc", "abcabc"); |
| r += expect_result_unmatch ("abc", "abcabcabc"); |
| r += expect_result_unmatch ("abc", "abcabcabcabc"); |
| r += expect_result_unmatch ("ABCABC", "ABC"); |
| r += expect_result_unmatch ("ABCABCABC", "ABC"); |
| r += expect_result_unmatch ("ABCABCABCABC", "ABC"); |
| r += expect_result_unmatch ("123\\\\\\\\\\\\\\\\\\\\", "123\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\\\\\", "\\\\\\\\"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\123\\\\", "\\\\\\\\123"); |
| r += expect_result_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\\"); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, one otherwise */ |
| static unsigned int |
| expect_result_case_unmatch_n (const char *const quoted, |
| const size_t quoted_len, |
| const char *const unquoted, |
| const size_t unquoted_len, |
| const unsigned int line_num) |
| { |
| unsigned int ret2; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (NULL != unquoted); |
| |
| /* THe check: MHD_str_equal_quoted_bin_n () */ |
| ret2 = 0; |
| if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret2 = 1; |
| } |
| |
| return ret2; |
| } |
| |
| |
| #define expect_result_case_unmatch(q,u) \ |
| expect_result_case_unmatch_n(q,MHD_STATICSTR_LEN_(q),\ |
| u,MHD_STATICSTR_LEN_(u),__LINE__) |
| |
| static unsigned int |
| check_unmatch_case (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| r += expect_result_case_unmatch ("a", "A"); |
| r += expect_result_case_unmatch ("abC", "aBc"); |
| r += expect_result_case_unmatch ("AbCdeF", "aBCdEF"); |
| r += expect_result_case_unmatch ("a\0" "Bc", "a\0" "bC"); |
| r += expect_result_case_unmatch ("Abc\\\"", "abC\""); |
| r += expect_result_case_unmatch ("\\\"aBc", "\"abc"); |
| r += expect_result_case_unmatch ("abc\\\\", "ABC\\"); |
| r += expect_result_case_unmatch ("\\\\ABC", "\\abc"); |
| r += expect_result_case_unmatch ("\\\\ZYX", "\\ZYx"); |
| r += expect_result_case_unmatch ("abc", "ABC"); |
| r += expect_result_case_unmatch ("ABCabc", "abcABC"); |
| r += expect_result_case_unmatch ("abcXYZ", "ABCxyz"); |
| r += expect_result_case_unmatch ("AbCdEfABCabc", "ABcdEFabcABC"); |
| r += expect_result_case_unmatch ("a\\\\bc", "A\\BC"); |
| r += expect_result_case_unmatch ("ABCa\\\\bc", "abcA\\BC"); |
| r += expect_result_case_unmatch ("abcXYZ\\\\", "ABCxyz\\"); |
| r += expect_result_case_unmatch ("\\\\AbCdEfABCabc", "\\ABcdEFabcABC"); |
| |
| return r; |
| } |
| |
| |
| /* return zero if succeed, one otherwise */ |
| static unsigned int |
| expect_result_caseless_unmatch_n (const char *const quoted, |
| const size_t quoted_len, |
| const char *const unquoted, |
| const size_t unquoted_len, |
| const unsigned int line_num) |
| { |
| unsigned int ret2; |
| unsigned int ret3; |
| |
| mhd_assert (NULL != quoted); |
| mhd_assert (NULL != unquoted); |
| |
| /* The check: MHD_str_equal_quoted_bin_n () */ |
| ret2 = 0; |
| if (MHD_str_equal_quoted_bin_n (quoted, quoted_len, unquoted, unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret2 = 1; |
| } |
| |
| /* The check: MHD_str_equal_quoted_bin_n () */ |
| ret3 = 0; |
| if (MHD_str_equal_caseless_quoted_bin_n (quoted, quoted_len, unquoted, |
| unquoted_len)) |
| { |
| fprintf (stderr, |
| "'MHD_str_equal_caseless_quoted_bin_n ()' FAILED: Wrong result:\n"); |
| /* This does NOT print part of the string after binary zero */ |
| fprintf (stderr, |
| "\tRESULT : MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> true\n" |
| "\tEXPECTED: MHD_str_equal_caseless_quoted_bin_n('%.*s', %u, " |
| "'%.*s', %u) -> false\n", |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len, |
| (int) quoted_len, quoted, (unsigned) quoted_len, |
| (int) unquoted_len, unquoted, (unsigned) unquoted_len); |
| fprintf (stderr, |
| "The check is at line: %u\n\n", line_num); |
| ret3 = 1; |
| } |
| |
| return ret2 + ret3; |
| } |
| |
| |
| #define expect_result_caseless_unmatch(q,u) \ |
| expect_result_caseless_unmatch_n(q,MHD_STATICSTR_LEN_(q),\ |
| u,MHD_STATICSTR_LEN_(u),__LINE__) |
| |
| |
| static unsigned int |
| check_unmatch_caseless (void) |
| { |
| unsigned int r = 0; /**< The number of errors */ |
| |
| /* Matched sequence except invalid backslash at the end */ |
| r += expect_result_caseless_unmatch ("a\\", "A"); |
| r += expect_result_caseless_unmatch ("abC\\", "abc"); |
| r += expect_result_caseless_unmatch ("a\0" "Bc\\", "a\0" "bc"); |
| r += expect_result_caseless_unmatch ("abc\\\"\\", "ABC\""); |
| r += expect_result_caseless_unmatch ("\\\"\\", "\""); |
| r += expect_result_caseless_unmatch ("\\\"ABC\\", "\"abc"); |
| r += expect_result_caseless_unmatch ("Abc\\\\\\", "abC\\"); |
| r += expect_result_caseless_unmatch ("\\\\\\", "\\"); |
| r += expect_result_caseless_unmatch ("\\\\aBc\\", "\\abC"); |
| /* Difference at binary zero */ |
| r += expect_result_caseless_unmatch ("a\0", "A"); |
| r += expect_result_caseless_unmatch ("A", "a\0"); |
| r += expect_result_caseless_unmatch ("abC\0", "abc"); |
| r += expect_result_caseless_unmatch ("abc", "ABc\0"); |
| r += expect_result_caseless_unmatch ("a\0" "bC\0", "a\0" "bc"); |
| r += expect_result_caseless_unmatch ("a\0" "bc", "A\0" "bc\0"); |
| r += expect_result_caseless_unmatch ("ABC\\\"\0", "abc\""); |
| r += expect_result_caseless_unmatch ("abc\\\"", "ABC\"\0"); |
| r += expect_result_caseless_unmatch ("\\\"aBc\0", "\"abc"); |
| r += expect_result_caseless_unmatch ("\\\"Abc", "\"abc\0"); |
| r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\\0", "\\\\\\\\"); |
| r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\\\0"); |
| r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\0" "\\\\", "\\\\\\\\"); |
| r += expect_result_caseless_unmatch ("\\\\\\\\\\\\\\\\", "\\\\\\\0" "\\"); |
| r += expect_result_caseless_unmatch ("\0" "aBc", "abc"); |
| r += expect_result_caseless_unmatch ("abc", "\0" "abC"); |
| r += expect_result_caseless_unmatch ("\0" "abc", "0abc"); |
| r += expect_result_caseless_unmatch ("0abc", "\0" "aBc"); |
| r += expect_result_caseless_unmatch ("xyZ", "xy" "\0" "z"); |
| r += expect_result_caseless_unmatch ("Xy" "\0" "z", "xyz"); |
| /* Difference after binary zero */ |
| r += expect_result_caseless_unmatch ("abc\0" "1", "aBC\0" "2"); |
| r += expect_result_caseless_unmatch ("a\0" "bcX", "a\0" "bcy"); |
| r += expect_result_caseless_unmatch ("\0" "abc\\\"2", "\0" "Abc\"1"); |
| r += expect_result_caseless_unmatch ("\0" "Abc1\\\"", "\0" "abc2\""); |
| r += expect_result_caseless_unmatch ("\0" "\\\"c", "\0" "\"d"); |
| r += expect_result_caseless_unmatch ("\\\"ab" "\0" "1C", "\"ab" "\0" "2C"); |
| r += expect_result_caseless_unmatch ("a\0" "BCDef2", "a\0" "bcdef1"); |
| r += expect_result_caseless_unmatch ("a\0" "bc2def", "a\0" "BC1def"); |
| r += expect_result_caseless_unmatch ("a\0" "1bcdeF", "a\0" "2bcdef"); |
| r += expect_result_caseless_unmatch ("abcde\0" "f2", "ABCDE\0" "f1"); |
| r += expect_result_caseless_unmatch ("\\\"ab" "\0" "XC", "\"ab" "\0" "yC"); |
| r += expect_result_caseless_unmatch ("a\0" "BCDefY", "a\0" "bcdefx"); |
| r += expect_result_caseless_unmatch ("a\0" "bczdef", "a\0" "BCXdef"); |
| r += expect_result_caseless_unmatch ("a\0" "YbcdeF", "a\0" "zbcdef"); |
| r += expect_result_caseless_unmatch ("abcde\0" "fy", "ABCDE\0" "fX"); |
| |
| return r; |
| } |
| |
| |
| int |
| main (int argc, char *argv[]) |
| { |
| unsigned int errcount = 0; |
| (void) argc; (void) argv; /* Unused. Silent compiler warning. */ |
| errcount += check_match (); |
| errcount += check_quote_failed (); |
| errcount += check_match_caseless (); |
| errcount += check_invalid (); |
| errcount += check_unmatch (); |
| errcount += check_unmatch_case (); |
| errcount += check_unmatch_caseless (); |
| if (0 == errcount) |
| printf ("All tests were passed without errors.\n"); |
| return errcount == 0 ? 0 : 1; |
| } |