gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] branch master updated: add post processor logic fix


From: gnunet
Subject: [libmicrohttpd] branch master updated: add post processor logic fix
Date: Thu, 26 Dec 2019 14:47:32 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository libmicrohttpd.

The following commit(s) were added to refs/heads/master by this push:
     new f34781c8 add post processor logic fix
f34781c8 is described below

commit f34781c87e48df6081eaf5defd1430f44013e8b6
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Dec 26 14:44:18 2019 +0100

    add post processor logic fix
---
 ChangeLog                           |  4 +++
 src/include/microhttpd.h            |  2 +-
 src/microhttpd/postprocessor.c      | 63 ++++++++++++++++++++++++++-----------
 src/microhttpd/test_postprocessor.c | 56 +++++++++++++++++++++++----------
 4 files changed, 90 insertions(+), 35 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6118da9b..c7f00d79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Thu Dec 26 14:43:27 CET 2019
+    Adding fix for urlencoding of keys without values in
+    post-processor logic. -CG
+
 Tue 24 Dec 2019 03:32:18 PM CET
     Adding patch from Ethan Tuttle with test case for urlencoding
     in post-processor for keys without values. -CG/ET
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index a25bb41a..b44fc40e 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -132,7 +132,7 @@ typedef intptr_t ssize_t;
  * Current version of the library.
  * 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00096900
+#define MHD_VERSION 0x00096901
 
 /**
  * MHD-internal return code for "YES".
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c
index e515b363..b7f6b108 100644
--- a/src/microhttpd/postprocessor.c
+++ b/src/microhttpd/postprocessor.c
@@ -215,8 +215,14 @@ struct MHD_PostProcessor
    * Used to ensure that we do always call 'ikvi' even if the
    * payload is empty (but not more than once).
    */
-  int must_ikvi;
+  bool must_ikvi;
 
+  /**
+   * Set if we still need to run the unescape logic
+   * on the key allocated at the end of this struct.
+   */ 
+  bool must_unescape_key;
+  
   /**
    * State of the parser.
    */
@@ -395,6 +401,7 @@ process_value (struct MHD_PostProcessor *pp,
     }
   }
   while ( (value_start != value_end) ||
+          (pp->must_ikvi) ||
           (xoff > 0) )
   {
     size_t delta = value_end - value_start;
@@ -425,6 +432,7 @@ process_value (struct MHD_PostProcessor *pp,
     MHD_unescape_plus (xbuf);
     xoff = MHD_http_unescape (xbuf);
     /* finally: call application! */
+    pp->must_ikvi = false;
     if (MHD_NO == pp->ikvi (pp->cls,
                             MHD_POSTDATA_KIND,
                             (const char *) &pp[1],        /* key */
@@ -466,7 +474,8 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
   const char *last_escape = NULL;
 
   poff = 0;
-  while ( (poff < post_data_len) &&
+  while ( ( (poff < post_data_len) ||
+            (pp->state == PP_Callback) ) &&
           (pp->state != PP_Error) )
   {
     switch (pp->state) {
@@ -478,6 +487,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
       /* key phase */
       if (NULL == start_key)
         start_key = &post_data[poff];
+      pp->must_ikvi = true;
       switch (post_data[poff])
       {
       case '=':
@@ -519,13 +529,27 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
         /* case 'value&' */
         end_value = &post_data[poff];
         poff++;
-        pp->state = PP_Callback;
+        if ( pp->must_ikvi ||
+             (start_value != end_value) )
+        {
+          pp->state = PP_Callback;
+        }
+        else
+        {
+          pp->buffer_pos = 0;
+          pp->value_offset = 0;
+          pp->state = PP_Init; 
+        }
+        continue;
       case '\n':
       case '\r':
         /* Case: 'value\n' or 'value\r' */
         end_value = &post_data[poff];
         poff++;
-        pp->state = PP_Done;
+        if (pp->must_ikvi)
+          pp->state = PP_Callback;
+        else
+          pp->state = PP_Done;
         break;
       case '%':
         last_escape = &post_data[poff];
@@ -564,7 +588,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
     case PP_Callback:
       if ( (pp->buffer_pos + (end_key - start_key) >
             pp->buffer_size) ||
-           (pp->buffer_pos + (end_key - start_key) >
+           (pp->buffer_pos + (end_key - start_key) <
             pp->buffer_pos) )
       {
         /* key too long, cannot parse! */
@@ -580,9 +604,14 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
         pp->buffer_pos += end_key - start_key;
         start_key = NULL;
         end_key = NULL;
+        pp->must_unescape_key = true;
+      }
+      if (pp->must_unescape_key)
+      {
         kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
         MHD_unescape_plus (kbuf);
         MHD_http_unescape (kbuf);
+        pp->must_unescape_key = false;
       }
       process_value (pp,
                      start_value,
@@ -591,6 +620,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
       pp->value_offset = 0;
       start_value = NULL;
       end_value = NULL;
+      pp->buffer_pos = 0;
       pp->state = PP_Init;
       break;
     default:
@@ -602,8 +632,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
   }
 
   /* save remaining data for next iteration */
-  if ( (NULL != start_key) &&
-       (PP_Init == pp->state) )
+  if (NULL != start_key) 
   {
     if (NULL == end_key) 
       end_key = &post_data[poff];
@@ -611,22 +640,20 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
             start_key,
             end_key - start_key);
     pp->buffer_pos += end_key - start_key;
+    pp->must_unescape_key = true;
+    start_key = NULL;
+    end_key = NULL;
   }
   if ( (NULL != start_value) &&
        (PP_ProcessValue == pp->state) )
   {
     /* compute key, if we have not already */
-    if (NULL != start_key)
+    if (pp->must_unescape_key)
     {
-      memcpy (&kbuf[pp->buffer_pos],
-              start_key,
-              end_key - start_key);
-      pp->buffer_pos += end_key - start_key;
-      start_key = NULL;
-      end_key = NULL;
       kbuf[pp->buffer_pos] = '\0'; /* 0-terminate key */
       MHD_unescape_plus (kbuf);
       MHD_http_unescape (kbuf);
+      pp->must_unescape_key = false;
     }
     if (NULL == end_value)
       end_value = &post_data[poff];
@@ -634,8 +661,8 @@ post_process_urlencoded (struct MHD_PostProcessor *pp,
                    start_value,
                    end_value,
                    last_escape);
+    pp->must_ikvi = false;
   }
-  
   return MHD_YES;
 }
 
@@ -953,7 +980,7 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
   /* newline is either at beginning of boundary or
      at least at the last character that we are sure
      is not part of the boundary */
-  if ( ( (MHD_YES == pp->must_ikvi) ||
+  if ( ( (pp->must_ikvi) ||
          (0 != newline) ) &&
        (MHD_NO == pp->ikvi (pp->cls,
                             MHD_POSTDATA_KIND,
@@ -968,7 +995,7 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
     pp->state = PP_Error;
     return MHD_NO;
   }
-  pp->must_ikvi = MHD_NO;
+  pp->must_ikvi = false;
   pp->value_offset += newline;
   (*ioffptr) += newline;
   return MHD_YES;
@@ -1155,7 +1182,7 @@ post_process_multipart (struct MHD_PostProcessor *pp,
       }
       break;
     case PP_ProcessEntryHeaders:
-      pp->must_ikvi = MHD_YES;
+      pp->must_ikvi = true;
       if (MHD_NO ==
           process_multipart_headers (pp,
                                      &ioff,
diff --git a/src/microhttpd/test_postprocessor.c 
b/src/microhttpd/test_postprocessor.c
index 4b0c9e07..2c37565c 100644
--- a/src/microhttpd/test_postprocessor.c
+++ b/src/microhttpd/test_postprocessor.c
@@ -80,6 +80,7 @@ const char *want[] = {
   NULL, NULL, NULL, NULL, NULL
 };
 
+
 static int
 mismatch (const char *a, const char *b)
 {
@@ -98,7 +99,9 @@ value_checker (void *cls,
                const char *filename,
                const char *content_type,
                const char *transfer_encoding,
-               const char *data, uint64_t off, size_t size)
+               const char *data,
+               uint64_t off,
+               size_t size)
 {
   int *want_off = cls;
   int idx = *want_off;
@@ -106,20 +109,27 @@ value_checker (void *cls,
 
 #if 0
   fprintf (stderr,
-           "VC: `%s' `%s' `%s' `%s' `%.*s'\n",
+           "VC: `%s' `%s' `%s' `%s' `%.*s' (%d)\n",
            key, filename, content_type, transfer_encoding,
            (int) size,
-           data);
+           data,
+           (int) size);
 #endif
   if ( (0 != off) && (0 == size) )
+  {
+    if (NULL == want[idx + 4])
+      *want_off = idx + 5;
     return MHD_YES;
+  }
   if ((idx < 0) ||
       (want[idx] == NULL) ||
       (0 != strcmp (key, want[idx])) ||
       (mismatch (filename, want[idx + 1])) ||
       (mismatch (content_type, want[idx + 2])) ||
       (mismatch (transfer_encoding, want[idx + 3])) ||
-      (0 != memcmp (data, &want[idx + 4][off], size)))
+      (0 != memcmp (data,
+                    &want[idx + 4][off],
+                    size)))
   {
     *want_off = -1;
     fprintf (stderr,
@@ -127,19 +137,27 @@ value_checker (void *cls,
              key, filename, content_type, transfer_encoding,
              (int) size,
              data);
+    fprintf (stderr,
+             "Wanted: `%s' `%s' `%s' `%s' `%s'\n",
+             want[idx],
+             want[idx+1],
+             want[idx+2],
+             want[idx+3],
+             want[idx+4]);
     fprintf (stderr,
              "Unexpected result: %d/%d/%d/%d/%d/%d/%d\n",
              (idx < 0),
              (want[idx] == NULL),
-             (0 != strcmp (key, want[idx])),
+             (NULL != want[idx]) && (0 != strcmp (key, want[idx])),
              (mismatch (filename, want[idx + 1])),
              (mismatch (content_type, want[idx + 2])),
              (mismatch (transfer_encoding, want[idx + 3])),
              (0 != memcmp (data, &want[idx + 4][off], size)));
-             
     return MHD_NO;
   }
-  if (off + size == strlen (want[idx + 4]))
+  if ( ( (NULL == want[idx+4]) &&
+         (0 == off + size) ) ||
+       (off + size == strlen (want[idx + 4])) )
     *want_off = idx + 5;
   return MHD_YES;
 }
@@ -185,8 +203,10 @@ test_urlencoding_case (unsigned int want_start,
   if (want_off != want_end)
   {
     fprintf (stderr,
-             "Test failed in line %u\n",
-             (unsigned int) __LINE__);
+             "Test failed in line %u: %u != %u\n",
+             (unsigned int) __LINE__,
+             want_off,
+             want_end);
     return 1;
   }
   return 0;
@@ -198,17 +218,20 @@ test_urlencoding (void)
 {
   unsigned int errorCount = 0;
 
-  errorCount += test_urlencoding_case (URL_START, URL_END, URL_DATA);
+  errorCount += test_urlencoding_case (URL_START,
+                                       URL_END,
+                                       URL_DATA);
   errorCount += test_urlencoding_case (URL_NOVALUE1_START,
                                        URL_NOVALUE1_END,
                                        URL_NOVALUE1_DATA);
   errorCount += test_urlencoding_case (URL_NOVALUE2_START,
                                        URL_NOVALUE2_END,
                                        URL_NOVALUE2_DATA);
-  fprintf (stderr,
-           "Test failed in line %u with %u errors\n",
-           (unsigned int) __LINE__,
-           errorCount);
+  if (0 != errorCount)
+    fprintf (stderr,
+             "Test failed in line %u with %u errors\n",
+             (unsigned int) __LINE__,
+             errorCount);
   return errorCount;
 }
 
@@ -419,8 +442,9 @@ test_empty_value (void)
   if (want_off != URL_EMPTY_VALUE_END)
   {
     fprintf (stderr,
-             "Test failed in line %u\n",
-             (unsigned int) __LINE__);
+             "Test failed in line %u at offset %d\n",
+             (unsigned int) __LINE__,
+             (int) want_off);
     return 8;
   }
   return 0;

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]