Просмотр исходного кода

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

Christian Grothoff 11 лет назад
Родитель
Сommit
ee47d16366
5 измененных файлов с 42 добавлено и 27 удалено
  1. 3 0
      ChangeLog
  2. 6 21
      src/microhttpd/connection.c
  3. 15 0
      src/microhttpd/internal.c
  4. 16 6
      src/microhttpd/internal.h
  5. 2 0
      src/microhttpd/postprocessor.c

+ 3 - 0
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
 

+ 6 - 21
src/microhttpd/connection.c

@@ -148,21 +148,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
@@ -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);

+ 15 - 0
src/microhttpd/internal.c

@@ -104,6 +104,21 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...)
 #endif
 
 
+/**
+ * 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.

+ 16 - 6
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

+ 2 - 0
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;