libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit a22321bf1a3187ae9eaf0789ec477f2c9c7d81f7
parent bf92eff1f850b9d2ed436bc05f163457007cbdef
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu, 30 Aug 2012 19:17:17 +0000

fixing #2531

Diffstat:
MChangeLog | 6++++++
Msrc/daemon/connection.c | 66+++++++++++++++++++++++++++++++++++++++++++++++++-----------------
Msrc/daemon/digestauth.c | 16++++++++--------
Msrc/daemon/postprocessor.c | 2+-
Msrc/daemon/response.c | 12++++++------
5 files changed, 70 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,9 @@ +Thu Aug 30 21:12:56 CEST 2012 + Fixing URI argument parsing when string contained keys without + equals sign (i.e. '&bar&') in the middle of the argument (#2531). + Also replacing 'strstr' with more efficient 'strchr' when + possible. -CG + Tue Aug 21 14:36:17 CEST 2012 Use "int" instead of "enum X" in 'va_arg' calls to be nice to compilers that use 'short' (i.e. 8 or 16 bit) enums but pass diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -1123,26 +1123,58 @@ parse_arguments (enum MHD_ValueKind kind, while (NULL != args) { - if (NULL == (equals = strstr (args, "="))) + equals = strchr (args, '='); + amper = strchr (args, '&'); + if (NULL == amper) { - /* add with 'value' NULL */ + /* last argument */ + if (NULL == equals) + { + /* got 'foo', add key 'foo' with NULL for value */ + connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, + connection, + args); + return connection_add_header (connection, + args, + NULL, + kind); + } + /* got 'foo=bar' */ + equals[0] = '\0'; + equals++; + connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, + connection, + args); + connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, + connection, + equals); + return connection_add_header (connection, args, equals, kind); + } + /* amper is non-NULL here */ + amper[0] = '\0'; + amper++; + if ( (NULL == equals) || + (equals >= amper) ) + { + /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */ connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); - - return connection_add_header (connection, - args, - NULL, - kind); + if (MHD_NO == + connection_add_header (connection, + args, + NULL, + kind)) + return MHD_NO; + /* continue with 'bar' */ + args = amper; + continue; + } + /* equals and amper are non-NULL here, and equals < amper, + so we got regular 'foo=value&bar...'-kind of argument */ equals[0] = '\0'; equals++; - amper = strstr (equals, "&"); - if (amper != NULL) - { - amper[0] = '\0'; - amper++; - } connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); @@ -1265,14 +1297,14 @@ parse_initial_message_line (struct MHD_Connection *connection, char *line) char *httpVersion; char *args; - if (NULL == (uri = strstr (line, " "))) + if (NULL == (uri = strchr (line, ' '))) return MHD_NO; /* serious error */ uri[0] = '\0'; connection->method = line; uri++; while (uri[0] == ' ') uri++; - httpVersion = strstr (uri, " "); + httpVersion = strchr (uri, ' '); if (httpVersion != NULL) { httpVersion[0] = '\0'; @@ -1283,7 +1315,7 @@ parse_initial_message_line (struct MHD_Connection *connection, char *line) = connection->daemon->uri_log_callback (connection->daemon-> uri_log_callback_cls, uri); - args = strstr (uri, "?"); + args = strchr (uri, '?'); if (NULL != args) { args[0] = '\0'; @@ -1638,7 +1670,7 @@ process_header_line (struct MHD_Connection *connection, char *line) char *colon; /* line should be normal header line, find colon */ - colon = strstr (line, ":"); + colon = strchr (line, ':'); if (colon == NULL) { /* error in header line, die hard */ diff --git a/src/daemon/digestauth.c b/src/daemon/digestauth.c @@ -225,20 +225,20 @@ lookup_sub_value(char *dest, return 0; while ('\0' != *ptr) { - if (NULL == (eq = strstr (ptr, "="))) + if (NULL == (eq = strchr (ptr, '='))) return 0; q1 = eq + 1; while (' ' == *q1) q1++; if ('\"' != *q1) { - q2 = strstr (q1, ","); + q2 = strchr (q1, ','); qn = q2; } else { q1++; - q2 = strstr (q1, "\""); + q2 = strchr (q1, '\"'); if (NULL == q2) return 0; /* end quote not found */ qn = q2 + 1; @@ -274,7 +274,7 @@ lookup_sub_value(char *dest, } if (NULL == qn) return 0; - ptr = strstr (qn, ","); + ptr = strchr (qn, ','); if (NULL == ptr) return 0; ptr++; @@ -490,7 +490,7 @@ check_argument_match (struct MHD_Connection *connection, while ( (argp != NULL) && (argp[0] != '\0') ) { - equals = strstr (argp, "="); + equals = strchr (argp, '='); if (equals == NULL) { /* add with 'value' NULL */ @@ -504,7 +504,7 @@ check_argument_match (struct MHD_Connection *connection, } equals[0] = '\0'; equals++; - amper = strstr (equals, "&"); + amper = strchr (equals, '&'); if (amper != NULL) { amper[0] = '\0'; @@ -639,7 +639,7 @@ MHD_digest_auth_check(struct MHD_Connection *connection, return MHD_NO; } { - const char *args = strstr (uri, "?"); + const char *args = strchr (uri, '?'); if (args == NULL) args = ""; else @@ -830,7 +830,7 @@ MHD_basic_auth_get_username_password(struct MHD_Connection *connection, return NULL; } /* Find user:password pattern */ - separator = strstr(decode, ":"); + separator = strchr (decode, ':'); if (separator == NULL) { #if HAVE_MESSAGES diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c @@ -539,7 +539,7 @@ try_get_value (const char *buf, const char *key, char **destination) } if (spos[klen + 1] != '"') return; /* not quoted */ - if (NULL == (endv = strstr (&spos[klen + 2], "\""))) + if (NULL == (endv = strchr (&spos[klen + 2], '\"'))) return; /* no end-quote */ vlen = endv - spos - klen - 1; *destination = malloc (vlen); diff --git a/src/daemon/response.c b/src/daemon/response.c @@ -50,12 +50,12 @@ add_response_entry (struct MHD_Response *response, (NULL == content) || (0 == strlen (header)) || (0 == strlen (content)) || - (NULL != strstr (header, "\t")) || - (NULL != strstr (header, "\r")) || - (NULL != strstr (header, "\n")) || - (NULL != strstr (content, "\t")) || - (NULL != strstr (content, "\r")) || - (NULL != strstr (content, "\n")) ) + (NULL != strchr (header, '\t')) || + (NULL != strchr (header, '\r')) || + (NULL != strchr (header, '\n')) || + (NULL != strchr (content, '\t')) || + (NULL != strchr (content, '\r')) || + (NULL != strchr (content, '\n')) ) return MHD_NO; if (NULL == (hdr = malloc (sizeof (struct MHD_HTTP_Header)))) return MHD_NO;