libmicrohttpd

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

commit ee47d1636680e4132ba825a3786216b4d2fccf7f
parent 9e8530eea82f0c1d84f1eff5f01229e7ab6fd6d3
Author: Christian Grothoff <christian@grothoff.org>
Date:   Mon, 29 Sep 2014 20:35:58 +0000

fix '+' unescape logic for URI-encoded POST data

Diffstat:
MChangeLog | 3+++
Msrc/microhttpd/connection.c | 27++++++---------------------
Msrc/microhttpd/internal.c | 15+++++++++++++++
Msrc/microhttpd/internal.h | 22++++++++++++++++------
Msrc/microhttpd/postprocessor.c | 2++
5 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,6 @@ +Mon Sep 29 22:25:34 CEST 2014 + Properly decode '+' in URL-encoded POST data. -CG/KM + Fri Sep 12 17:32:09 CEST 2014 Fix --disable-dauth configure option (#3543). -doostee diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -149,21 +149,6 @@ MHD_get_connection_values (struct MHD_Connection *connection, /** - * Convert all occurences of '+' to ' '. - * - * @param arg string that is modified - */ -static void -escape_plus (char *arg) -{ - char *p; - - for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+')) - *p = ' '; -} - - -/** * This function can be used to add an entry to the HTTP headers of a * connection (so that the #MHD_get_connection_values function will * return them -- and the `struct MHD_PostProcessor` will also see @@ -1230,7 +1215,7 @@ parse_arguments (enum MHD_ValueKind kind, if (NULL == equals) { /* got 'foo', add key 'foo' with NULL for value */ - escape_plus (args); + MHD_unescape_plus (args); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); @@ -1242,11 +1227,11 @@ parse_arguments (enum MHD_ValueKind kind, /* got 'foo=bar' */ equals[0] = '\0'; equals++; - escape_plus (args); + MHD_unescape_plus (args); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); - escape_plus (equals); + MHD_unescape_plus (equals); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, equals); @@ -1259,7 +1244,7 @@ parse_arguments (enum MHD_ValueKind kind, (equals >= amper) ) { /* got 'foo&bar' or 'foo&bar=val', add key 'foo' with NULL for value */ - escape_plus (args); + MHD_unescape_plus (args); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); @@ -1278,11 +1263,11 @@ parse_arguments (enum MHD_ValueKind kind, so we got regular 'foo=value&bar...'-kind of argument */ equals[0] = '\0'; equals++; - escape_plus (args); + MHD_unescape_plus (args); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, args); - escape_plus (equals); + MHD_unescape_plus (equals); connection->daemon->unescape_callback (connection->daemon->unescape_callback_cls, connection, equals); diff --git a/src/microhttpd/internal.c b/src/microhttpd/internal.c @@ -105,6 +105,21 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...) /** + * Convert all occurences of '+' to ' '. + * + * @param arg string that is modified (in place), must be 0-terminated + */ +void +MHD_unescape_plus (char *arg) +{ + char *p; + + for (p=strchr (arg, '+'); NULL != p; p = strchr (p + 1, '+')) + *p = ' '; +} + + +/** * Process escape sequences ('%HH') Updates val in place; the * result should be UTF-8 encoded and cannot be larger than the input. * The result must also still be 0-terminated. diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -726,7 +726,7 @@ struct MHD_Connection int client_aware; /** - * Socket for this connection. Set to MHD_INVALID_SOCKET if + * Socket for this connection. Set to #MHD_INVALID_SOCKET if * this connection has died (daemon should clean * up in that case). */ @@ -741,7 +741,7 @@ struct MHD_Connection int read_closed; /** - * Set to MHD_YES if the thread has been joined. + * Set to #MHD_YES if the thread has been joined. */ int thread_joined; @@ -878,7 +878,7 @@ typedef void * (*LogCallback)(void * cls, /** * Signature of function called to unescape URIs. See also - * MHD_http_unescape. + * #MHD_http_unescape(). * * @param cls closure * @param conn connection handle @@ -1017,7 +1017,7 @@ struct MHD_Daemon LogCallback uri_log_callback; /** - * Closure argument to uri_log_callback. + * Closure argument to @e uri_log_callback. */ void *uri_log_callback_cls; @@ -1027,7 +1027,7 @@ struct MHD_Daemon UnescapeCallback unescape_callback; /** - * Closure for unescape callback. + * Closure for @e unescape_callback. */ void *unescape_callback_cls; @@ -1398,7 +1398,7 @@ struct MHD_Daemon /** - * Equivalent to time(NULL) but tries to use some sort of monotonic + * Equivalent to `time(NULL)` but tries to use some sort of monotonic * clock that isn't affected by someone setting the system real time * clock. * @@ -1407,4 +1407,14 @@ struct MHD_Daemon time_t MHD_monotonic_time(void); + +/** + * Convert all occurences of '+' to ' '. + * + * @param arg string that is modified (in place), must be 0-terminated + */ +void +MHD_escape_plus (char *arg); + + #endif diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c @@ -381,6 +381,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, return MHD_YES; /* no '=' yet */ buf[pp->buffer_pos] = '\0'; /* 0-terminate key */ pp->buffer_pos = 0; /* reset for next key */ + MHD_unescape_plus (buf); MHD_http_unescape (NULL, NULL, buf); poff += equals + 1; pp->state = PP_ProcessValue; @@ -441,6 +442,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, /* unescape */ xbuf[xoff] = '\0'; /* 0-terminate in preparation */ + MHD_unescape_plus (xbuf); xoff = MHD_http_unescape (NULL, NULL, xbuf); /* finally: call application! */ pp->must_ikvi = MHD_NO;