diff --git a/ChangeLog b/ChangeLog index 1baf92b2..f9682194 100644 --- a/ChangeLog +++ b/ChangeLog @@ -18,6 +18,7 @@ Changes in 2.0.2-alpha: o Add an event_get_base() function to return the base assigned to an event. o New function to automate connecting on a socket-based bufferevent. o New functions to automate listening for incoming TCP connections. + o Do case-insensitive checks with a locale-independent comparison function. Changes in 2.0.1-alpha: diff --git a/evdns.c b/evdns.c index 67dc575f..bcb55fce 100644 --- a/evdns.c +++ b/evdns.c @@ -988,9 +988,6 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) { sizeof(tmp_name))<0) \ goto err; \ } while(0) -#ifdef _MSC_VER -#define strcasecmp _strcmpi -#endif #define TEST_NAME \ do { tmp_name[0] = '\0'; \ cmp_name[0] = '\0'; \ @@ -1005,7 +1002,7 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) { if (strcmp(tmp_name, cmp_name) == 0) \ name_matches = 1; \ } else { \ - if (strcasecmp(tmp_name, cmp_name) == 0) \ + if (evutil_strcasecmp(tmp_name, cmp_name) == 0) \ name_matches = 1; \ } \ } while(0) diff --git a/evutil.c b/evutil.c index 2e1fa9c3..5b380344 100644 --- a/evutil.c +++ b/evutil.c @@ -734,3 +734,34 @@ const char EVUTIL_TOLOWER_TABLE[256] = { 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, }; + +int +evutil_strcasecmp(const char *s1, const char *s2) +{ + char c1, c2; + while (1) { + c1 = EVUTIL_TOLOWER(*s1++); + c2 = EVUTIL_TOLOWER(*s2++); + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + else if (c1 == 0) + return 0; + } +} +int evutil_strncasecmp(const char *s1, const char *s2, size_t n) +{ + char c1, c2; + while (n--) { + c1 = EVUTIL_TOLOWER(*s1++); + c2 = EVUTIL_TOLOWER(*s2++); + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + else if (c1 == 0) + return 0; + } + return 0; +} diff --git a/http.c b/http.c index 496e495b..282fd0e0 100644 --- a/http.c +++ b/http.c @@ -96,11 +96,6 @@ #include "http-internal.h" #include "mm-internal.h" -#ifdef WIN32 -#define strcasecmp _stricmp -#define strncasecmp _strnicmp -#endif - #ifndef _EVENT_HAVE_GETNAMEINFO #define NI_MAXSERV 32 #define NI_MAXHOST 1025 @@ -423,10 +418,10 @@ evhttp_is_connection_close(int flags, struct evkeyvalq* headers) if (flags & EVHTTP_PROXY_REQUEST) { /* proxy connection */ const char *connection = evhttp_find_header(headers, "Proxy-Connection"); - return (connection == NULL || strcasecmp(connection, "keep-alive") != 0); + return (connection == NULL || evutil_strcasecmp(connection, "keep-alive") != 0); } else { const char *connection = evhttp_find_header(headers, "Connection"); - return (connection != NULL && strcasecmp(connection, "close") == 0); + return (connection != NULL && evutil_strcasecmp(connection, "close") == 0); } } @@ -435,7 +430,7 @@ evhttp_is_connection_keepalive(struct evkeyvalq* headers) { const char *connection = evhttp_find_header(headers, "Connection"); return (connection != NULL - && strncasecmp(connection, "keep-alive", 10) == 0); + && evutil_strncasecmp(connection, "keep-alive", 10) == 0); } static void @@ -1330,7 +1325,7 @@ evhttp_find_header(const struct evkeyvalq *headers, const char *key) struct evkeyval *header; TAILQ_FOREACH(header, headers, next) { - if (strcasecmp(header->key, key) == 0) + if (evutil_strcasecmp(header->key, key) == 0) return (header->value); } @@ -1363,7 +1358,7 @@ evhttp_remove_header(struct evkeyvalq *headers, const char *key) struct evkeyval *header; TAILQ_FOREACH(header, headers, next) { - if (strcasecmp(header->key, key) == 0) + if (evutil_strcasecmp(header->key, key) == 0) break; } @@ -1559,7 +1554,7 @@ evhttp_get_body_length(struct evhttp_request *req) if (content_length == NULL && connection == NULL) req->ntoread = -1; else if (content_length == NULL && - strcasecmp(connection, "Close") != 0) { + evutil_strcasecmp(connection, "Close") != 0) { /* Bad combination, we don't know when it will end */ event_warnx("%s: we got no content length, but the " "server wants to keep the connection open: %s.", @@ -1598,7 +1593,7 @@ evhttp_get_body(struct evhttp_connection *evcon, struct evhttp_request *req) } evcon->state = EVCON_READING_BODY; xfer_enc = evhttp_find_header(req->input_headers, "Transfer-Encoding"); - if (xfer_enc != NULL && strcasecmp(xfer_enc, "chunked") == 0) { + if (xfer_enc != NULL && evutil_strcasecmp(xfer_enc, "chunked") == 0) { req->chunked = 1; req->ntoread = -1; } else { diff --git a/util-internal.h b/util-internal.h index 569cafa2..cc61ea24 100644 --- a/util-internal.h +++ b/util-internal.h @@ -111,6 +111,8 @@ extern const char EVUTIL_TOUPPER_TABLE[]; extern const char EVUTIL_TOLOWER_TABLE[]; #define EVUTIL_TOLOWER(c) (EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]) #define EVUTIL_TOUPPER(c) (EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]) +int evutil_strcasecmp(const char *, const char *); +int evutil_strncasecmp(const char *, const char *, size_t); /** Helper macro. If we know that a given pointer points to a field in a structure, return a pointer to the structure itself. Used to implement