aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-07-10 15:06:46 +0200
committerChristian Grothoff <christian@grothoff.org>2020-07-10 15:06:46 +0200
commit9b39de8d9eb11807d13ff7fd8e7a27ab84c12454 (patch)
treeedcc84ec05326501cfddff52a052063d57825922
parent8c77370410297ae698a1b034da203fd567867203 (diff)
downloadlibmicrohttpd-9b39de8d9eb11807d13ff7fd8e7a27ab84c12454.tar.gz
libmicrohttpd-9b39de8d9eb11807d13ff7fd8e7a27ab84c12454.zip
fix postprocessor parser issue discovered by MD
-rw-r--r--ChangeLog3
-rw-r--r--src/microhttpd/postprocessor.c48
-rw-r--r--src/microhttpd/test_postprocessor.c2
-rw-r--r--src/microhttpd/test_postprocessor_md.c25
4 files changed, 48 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index a4bafe30..92e9ce6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
1Fri Jul 10 15:04:51 CEST 2020
2 Fixed Postprocessor URL-encoded parsing if '%' fell on boundary. -CG/MD
3
1Thu 02 Jul 2020 09:56:23 PM CEST 4Thu 02 Jul 2020 09:56:23 PM CEST
2 Fixed return type of MHD_queue_basic_auth_fail_response. -CA/CG 5 Fixed return type of MHD_queue_basic_auth_fail_response. -CA/CG
3 6
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c
index 1eb33ed6..ecdef5a8 100644
--- a/src/microhttpd/postprocessor.c
+++ b/src/microhttpd/postprocessor.c
@@ -353,21 +353,17 @@ MHD_create_post_processor (struct MHD_Connection *connection,
353 353
354 354
355/** 355/**
356 * Give a (possibly partial) value to the 356 * Give a (possibly partial) value to the application callback. We have some
357 * application callback. We have some 357 * part of the value in the 'pp->xbuf', the rest is between @a value_start and
358 * part of the value in the 'pp->xbuf', the 358 * @a value_end. If @a last_escape is non-NULL, there may be an incomplete
359 * rest is between @a value_start and @a value_end. 359 * escape sequence at at @a value_escape between @a value_start and @a
360 * If @a last_escape is non-NULL, there may be 360 * value_end which we should preserve in 'pp->xbuf' for the future.
361 * an incomplete escape sequence at at @a value_escape
362 * between @a value_start and @a value_end which
363 * we should preserve in 'pp->xbuf' for the future.
364 * 361 *
365 * Unescapes the value and calls the iterator 362 * Unescapes the value and calls the iterator together with the key. The key
366 * together with the key. The key must already 363 * must already be in the key buffer allocated and 0-terminated at the end of
367 * be in the key buffer allocated and 0-terminated 364 * @a pp at the time of the call.
368 * at the end of @a pp at the time of the call.
369 * 365 *
370 * @param pp post processor to act upon 366 * @param[in,out] pp post processor to act upon
371 * @param value_start where in memory is the value 367 * @param value_start where in memory is the value
372 * @param value_end where does the value end 368 * @param value_end where does the value end
373 * @param last_escape last '%'-sign in value range, 369 * @param last_escape last '%'-sign in value range,
@@ -404,6 +400,7 @@ process_value (struct MHD_PostProcessor *pp,
404 (xoff > 0) ) 400 (xoff > 0) )
405 { 401 {
406 size_t delta = value_end - value_start; 402 size_t delta = value_end - value_start;
403 bool cut = false;
407 404
408 if (delta > XBUF_SIZE - xoff) 405 if (delta > XBUF_SIZE - xoff)
409 delta = XBUF_SIZE - xoff; 406 delta = XBUF_SIZE - xoff;
@@ -414,14 +411,23 @@ process_value (struct MHD_PostProcessor *pp,
414 /* find if escape sequence is at the end of the processing buffer; 411 /* find if escape sequence is at the end of the processing buffer;
415 if so, exclude those from processing (reduce delta to point at 412 if so, exclude those from processing (reduce delta to point at
416 end of processed region) */ 413 end of processed region) */
417 if (delta >= XBUF_SIZE - 2) 414 if ( (xoff + delta > 0) &&
415 ('%' == xbuf[xoff + delta - 1]) )
418 { 416 {
419 if ((xoff + delta > 0) && 417 cut = (delta != XBUF_SIZE - xoff);
420 ('%' == xbuf[xoff + delta - 1])) 418 delta--;
421 delta--; 419 pp->xbuf[0] = '%';
422 else if ((xoff + delta > 1) && 420 pp->xbuf_pos = 1;
423 ('%' == xbuf[xoff + delta - 2])) 421 }
424 delta -= 2; 422 else if ( (xoff + delta > 1) &&
423 ('%' == xbuf[xoff + delta - 2]) )
424 {
425 memcpy (pp->xbuf,
426 &xbuf[xoff + delta - 2],
427 2);
428 pp->xbuf_pos = 2;
429 cut = (delta != XBUF_SIZE - xoff);
430 delta -= 2;
425 } 431 }
426 xoff += delta; 432 xoff += delta;
427 value_start += delta; 433 value_start += delta;
@@ -447,6 +453,8 @@ process_value (struct MHD_PostProcessor *pp,
447 } 453 }
448 pp->value_offset += xoff; 454 pp->value_offset += xoff;
449 xoff = 0; 455 xoff = 0;
456 if (cut)
457 break;
450 } 458 }
451} 459}
452 460
diff --git a/src/microhttpd/test_postprocessor.c b/src/microhttpd/test_postprocessor.c
index b62e7ff9..b77bfb26 100644
--- a/src/microhttpd/test_postprocessor.c
+++ b/src/microhttpd/test_postprocessor.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2007,2013,2019 Christian Grothoff 3 Copyright (C) 2007, 2013, 2019, 2020 Christian Grothoff
4 4
5 libmicrohttpd is free software; you can redistribute it and/or modify 5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
diff --git a/src/microhttpd/test_postprocessor_md.c b/src/microhttpd/test_postprocessor_md.c
index bfa2d76a..07400f09 100644
--- a/src/microhttpd/test_postprocessor_md.c
+++ b/src/microhttpd/test_postprocessor_md.c
@@ -114,13 +114,22 @@ post_data_iterator2 (void *cls,
114 uint64_t off, 114 uint64_t off,
115 size_t size) 115 size_t size)
116{ 116{
117 printf ("%s\t%s\n", key, data); 117 static char seen[16];
118
119 printf ("%s\t%s@ %llu\n",
120 key,
121 data,
122 (unsigned long long) off);
118 if (0 == strcmp (key, "text")) 123 if (0 == strcmp (key, "text"))
119 { 124 {
120 if ( (10 != size) || 125 if (off + size > sizeof (seen))
121 (0 != memcmp (data, "text, text", 10)) ) 126 exit (6);
122 exit (5); 127 memcpy (&seen[off],
123 found |= 1; 128 data,
129 size);
130 if ( (10 == off + size) &&
131 (0 == memcmp (seen, "text, text", 10)) )
132 found |= 1;
124 } 133 }
125 return MHD_YES; 134 return MHD_YES;
126} 135}
@@ -151,7 +160,6 @@ main (int argc, char *argv[])
151 exit (3); 160 exit (3);
152 if (found != 15) 161 if (found != 15)
153 exit (2); 162 exit (2);
154
155 found = 0; 163 found = 0;
156 postprocessor = malloc (sizeof (struct MHD_PostProcessor) 164 postprocessor = malloc (sizeof (struct MHD_PostProcessor)
157 + 0x1000 + 1); 165 + 0x1000 + 1);
@@ -165,9 +173,8 @@ main (int argc, char *argv[])
165 postprocessor->buffer_size = 0x1000; 173 postprocessor->buffer_size = 0x1000;
166 postprocessor->state = PP_Init; 174 postprocessor->state = PP_Init;
167 postprocessor->skip_rn = RN_Inactive; 175 postprocessor->skip_rn = RN_Inactive;
168 MHD_post_process (postprocessor, "text=text%2C+text", 11 + 6); 176 MHD_post_process (postprocessor, "text=text%2", 11);
169 // MHD_post_process (postprocessor, "text=text%2", 11); 177 MHD_post_process (postprocessor, "C+text", 6);
170 // MHD_post_process (postprocessor, "C+text", 6);
171 MHD_post_process (postprocessor, "", 0); 178 MHD_post_process (postprocessor, "", 0);
172 MHD_destroy_post_processor (postprocessor); 179 MHD_destroy_post_processor (postprocessor);
173 if (found != 1) 180 if (found != 1)