Bladeren bron

fix postprocessor parser issue discovered by MD

Christian Grothoff 5 jaren geleden
bovenliggende
commit
9b39de8d9e
4 gewijzigde bestanden met toevoegingen van 48 en 30 verwijderingen
  1. 3 0
      ChangeLog
  2. 28 20
      src/microhttpd/postprocessor.c
  3. 1 1
      src/microhttpd/test_postprocessor.c
  4. 16 9
      src/microhttpd/test_postprocessor_md.c

+ 3 - 0
ChangeLog

@@ -1,3 +1,6 @@
+Fri Jul 10 15:04:51 CEST 2020
+    Fixed Postprocessor URL-encoded parsing if '%' fell on boundary. -CG/MD
+
 Thu 02 Jul 2020 09:56:23 PM CEST
     Fixed return type of MHD_queue_basic_auth_fail_response. -CA/CG
 

+ 28 - 20
src/microhttpd/postprocessor.c

@@ -353,21 +353,17 @@ MHD_create_post_processor (struct MHD_Connection *connection,
 
 
 /**
- * Give a (possibly partial) value to the
- * application callback.  We have some
- * part of the value in the 'pp->xbuf', the
- * rest is between @a value_start and @a value_end.
- * If @a last_escape is non-NULL, there may be
- * an incomplete escape sequence at at @a value_escape
- * between @a value_start and @a value_end which
- * we should preserve in 'pp->xbuf' for the future.
+ * Give a (possibly partial) value to the application callback.  We have some
+ * part of the value in the 'pp->xbuf', the rest is between @a value_start and
+ * @a value_end.  If @a last_escape is non-NULL, there may be an incomplete
+ * escape sequence at at @a value_escape between @a value_start and @a
+ * value_end which we should preserve in 'pp->xbuf' for the future.
  *
- * Unescapes the value and calls the iterator
- * together with the key.  The key must already
- * be in the key buffer allocated and 0-terminated
- * at the end of @a pp at the time of the call.
+ * Unescapes the value and calls the iterator together with the key.  The key
+ * must already be in the key buffer allocated and 0-terminated at the end of
+ * @a pp at the time of the call.
  *
- * @param pp post processor to act upon
+ * @param[in,out] pp post processor to act upon
  * @param value_start where in memory is the value
  * @param value_end where does the value end
  * @param last_escape last '%'-sign in value range,
@@ -404,6 +400,7 @@ process_value (struct MHD_PostProcessor *pp,
           (xoff > 0) )
   {
     size_t delta = value_end - value_start;
+    bool cut = false;
 
     if (delta > XBUF_SIZE - xoff)
       delta = XBUF_SIZE - xoff;
@@ -414,14 +411,23 @@ process_value (struct MHD_PostProcessor *pp,
     /* find if escape sequence is at the end of the processing buffer;
        if so, exclude those from processing (reduce delta to point at
        end of processed region) */
-    if (delta >= XBUF_SIZE - 2)
+    if ( (xoff + delta > 0) &&
+         ('%' == xbuf[xoff + delta - 1]) )
     {
-      if ((xoff + delta > 0) &&
-          ('%' == xbuf[xoff + delta - 1]))
-        delta--;
-      else if ((xoff + delta > 1) &&
-               ('%' == xbuf[xoff + delta - 2]))
-        delta -= 2;
+      cut = (delta != XBUF_SIZE - xoff);
+      delta--;
+      pp->xbuf[0] = '%';
+      pp->xbuf_pos = 1;
+    }
+    else if ( (xoff + delta > 1) &&
+              ('%' == xbuf[xoff + delta - 2]) )
+    {
+      memcpy (pp->xbuf,
+              &xbuf[xoff + delta - 2],
+              2);
+      pp->xbuf_pos = 2;
+      cut = (delta != XBUF_SIZE - xoff);
+      delta -= 2;
     }
     xoff += delta;
     value_start += delta;
@@ -447,6 +453,8 @@ process_value (struct MHD_PostProcessor *pp,
     }
     pp->value_offset += xoff;
     xoff = 0;
+    if (cut)
+      break;
   }
 }
 

+ 1 - 1
src/microhttpd/test_postprocessor.c

@@ -1,6 +1,6 @@
 /*
      This file is part of libmicrohttpd
-     Copyright (C) 2007,2013,2019 Christian Grothoff
+     Copyright (C) 2007, 2013, 2019, 2020 Christian Grothoff
 
      libmicrohttpd is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published

+ 16 - 9
src/microhttpd/test_postprocessor_md.c

@@ -114,13 +114,22 @@ post_data_iterator2 (void *cls,
                      uint64_t off,
                      size_t size)
 {
-  printf ("%s\t%s\n", key, data);
+  static char seen[16];
+
+  printf ("%s\t%s@ %llu\n",
+          key,
+          data,
+          (unsigned long long) off);
   if (0 == strcmp (key, "text"))
   {
-    if ( (10 != size) ||
-         (0 != memcmp (data, "text, text", 10)) )
-      exit (5);
-    found |= 1;
+    if (off + size > sizeof (seen))
+      exit (6);
+    memcpy (&seen[off],
+            data,
+            size);
+    if ( (10 == off + size) &&
+         (0 == memcmp (seen, "text, text", 10)) )
+      found |= 1;
   }
   return MHD_YES;
 }
@@ -151,7 +160,6 @@ main (int argc, char *argv[])
     exit (3);
   if (found != 15)
     exit (2);
-
   found = 0;
   postprocessor = malloc (sizeof (struct MHD_PostProcessor)
                           + 0x1000 + 1);
@@ -165,9 +173,8 @@ main (int argc, char *argv[])
   postprocessor->buffer_size = 0x1000;
   postprocessor->state = PP_Init;
   postprocessor->skip_rn = RN_Inactive;
-  MHD_post_process (postprocessor, "text=text%2C+text", 11 + 6);
-  // MHD_post_process (postprocessor, "text=text%2", 11);
-  // MHD_post_process (postprocessor, "C+text", 6);
+  MHD_post_process (postprocessor, "text=text%2", 11);
+  MHD_post_process (postprocessor, "C+text", 6);
   MHD_post_process (postprocessor, "", 0);
   MHD_destroy_post_processor (postprocessor);
   if (found != 1)