From e93439da71e027cafe5b2788a997cbfc85d193c8 Mon Sep 17 00:00:00 2001 From: "Evgeny Grin (Karlson2k)" Date: Mon, 8 May 2017 17:24:19 +0300 Subject: [PATCH] Added function for detection of token inside comma-separated string, added tests --- src/microhttpd/Makefile.am | 4 +++ src/microhttpd/internal.h | 3 ++ src/microhttpd/mhd_str.c | 58 ++++++++++++++++++++++++++++++++++++++ src/microhttpd/mhd_str.h | 42 +++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am index 3f1b828f..36121539 100644 --- a/src/microhttpd/Makefile.am +++ b/src/microhttpd/Makefile.am @@ -142,6 +142,7 @@ endif check_PROGRAMS = \ test_str_compare \ test_str_to_value \ + test_str_token \ test_http_reasons \ test_shutdown_select \ test_shutdown_poll \ @@ -251,6 +252,9 @@ test_str_compare_SOURCES = \ test_str_to_value_SOURCES = \ test_str.c test_helpers.h mhd_str.c +test_str_token_SOURCES = \ + test_str_token.c mhd_str.c + test_http_reasons_SOURCES = \ test_http_reasons.c \ reason_phrase.c mhd_str.c mhd_str.h diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h index cb6753c9..a9c46c6d 100644 --- a/src/microhttpd/internal.h +++ b/src/microhttpd/internal.h @@ -117,10 +117,13 @@ extern void *mhd_panic_cls; #define BUILTIN_NOT_REACHED #endif +#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_ */ + /** * State of the socket with respect to epoll (bitmask). diff --git a/src/microhttpd/mhd_str.c b/src/microhttpd/mhd_str.c index c5e9813c..bb10d26f 100644 --- a/src/microhttpd/mhd_str.c +++ b/src/microhttpd/mhd_str.c @@ -365,6 +365,64 @@ MHD_str_equal_caseless_n_ (const char * const str1, return !0; } + +/** + * Check whether @a str has case-insensitive @a token. + * Token could be surrounded by spaces and tabs and delimited by comma. + * Match succeed if substring between start, end (of string) or comma + * contains only case-insensitive token and optional spaces and tabs. + * @warning token must not contain null-charters except optional + * terminating null-character. + * @param str the string to check + * @param token the token to find + * @param token_len length of token, not including optional terminating + * null-character. + * @return non-zero if two strings are equal, zero otherwise. + */ +bool +MHD_str_has_token_caseless_ (const char * str, + const char * const token, + size_t token_len) +{ + if (0 == token_len) + return false; + + while (0 != *str) + { + size_t i; + /* Skip all whitespaces and empty tokens. */ + while (' ' == *str || '\t' == *str || ',' == *str) str++; + + /* Check for token match. */ + i = 0; + while (1) + { + const char sc = *(str++); + const char tc = token[i++]; + + if (0 == sc) + return false; + if ( (sc != tc) && + (toasciilower (sc) != toasciilower (tc)) ) + break; + if (i >= token_len) + { + /* Check whether substring match token fully or + * has additional unmatched chars at tail. */ + while (' ' == *str || '\t' == *str) str++; + /* End of (sub)string? */ + if (0 == *str || ',' == *str) + return true; + /* Unmatched chars at end of substring. */ + break; + } + } + /* Find next substring. */ + while (0 != *str && ',' != *str) str++; + } + return false; +} + #ifndef MHD_FAVOR_SMALL_CODE /* Use individual function for each case */ diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h index 0ee41717..410cc36e 100644 --- a/src/microhttpd/mhd_str.h +++ b/src/microhttpd/mhd_str.h @@ -30,11 +30,21 @@ #include #include +#ifdef HAVE_STDBOOL_H +#include +#endif /* HAVE_STDBOOL_H */ #ifdef MHD_FAVOR_SMALL_CODE #include "mhd_limits.h" #endif /* MHD_FAVOR_SMALL_CODE */ +#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_ */ + /* * Block of functions/macros that use US-ASCII charset as required by HTTP * standards. Not affected by current locale settings. @@ -71,6 +81,38 @@ MHD_str_equal_caseless_n_ (const char * const str1, const char * const str2, size_t maxlen); + +/** + * Check whether @a str has case-insensitive @a token. + * Token could be surrounded by spaces and tabs and delimited by comma. + * Match succeed if substring between start, end of string or comma + * contains only case-insensitive token and optional spaces and tabs. + * @warning token must not contain null-charters except optional + * terminating null-character. + * @param str the string to check + * @param token the token to find + * @param token_len length of token, not including optional terminating + * null-character. + * @return non-zero if two strings are equal, zero otherwise. + */ +bool +MHD_str_has_token_caseless_ (const char * str, + const char * const token, + size_t token_len); + +/** + * Check whether @a str has case-insensitive static @a tkn. + * Token could be surrounded by spaces and tabs and delimited by comma. + * Match succeed if substring between start, end of string or comma + * contains only case-insensitive token and optional spaces and tabs. + * @warning tkn must be static string + * @param str the string to check + * @param tkn the static string of token to find + * @return non-zero if two strings are equal, zero otherwise. + */ +#define MHD_str_has_s_token_caseless_(str,tkn) \ + MHD_str_has_token_caseless_((str),(tkn),MHD_STATICSTR_LEN_(tkn)) + #ifndef MHD_FAVOR_SMALL_CODE /* Use individual function for each case to improve speed */