aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-30 08:35:28 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-30 08:35:28 +0000
commit3fb38e694808965356d6a02447d186107701fa24 (patch)
tree0442c555f8e27afe9c5ce7e4b34412c797a8b735
parente524263be242e774d76377b04de9b033bd149d2e (diff)
downloadlibmicrohttpd-3fb38e694808965356d6a02447d186107701fa24.tar.gz
libmicrohttpd-3fb38e694808965356d6a02447d186107701fa24.zip
-fix post processor, expanded test suite to cover garbage before payload
-rw-r--r--ChangeLog4
-rw-r--r--src/microhttpd/postprocessor.c22
-rw-r--r--src/microhttpd/test_postprocessor.c65
3 files changed, 74 insertions, 17 deletions
diff --git a/ChangeLog b/ChangeLog
index 618ca1ce..158a045d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
1Wed Oct 30 09:34:20 CET 2013
2 Fixing issue in PostProcessor when getting partial boundary
3 at the beginning, expanding test suite. -CG
4
1Sun Oct 27 15:19:44 CET 2013 5Sun Oct 27 15:19:44 CET 2013
2 Implementing faster processing of upload data in multipart 6 Implementing faster processing of upload data in multipart
3 encoding (thanks to performance analysis by Adam Homolya). -CG 7 encoding (thanks to performance analysis by Adam Homolya). -CG
diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c
index 0fdf607f..892eabdd 100644
--- a/src/microhttpd/postprocessor.c
+++ b/src/microhttpd/postprocessor.c
@@ -533,18 +533,34 @@ find_boundary (struct MHD_PostProcessor *pp,
533 enum PP_State next_state, enum PP_State next_dash_state) 533 enum PP_State next_state, enum PP_State next_dash_state)
534{ 534{
535 char *buf = (char *) &pp[1]; 535 char *buf = (char *) &pp[1];
536 const char *dash;
536 537
537 if (pp->buffer_pos < 2 + blen) 538 if (pp->buffer_pos < 2 + blen)
538 { 539 {
539 if (pp->buffer_pos == pp->buffer_size) 540 if (pp->buffer_pos == pp->buffer_size)
540 pp->state = PP_Error; /* out of memory */ 541 pp->state = PP_Error; /* out of memory */
541 ++(*ioffptr); 542 // ++(*ioffptr);
542 return MHD_NO; /* not enough data */ 543 return MHD_NO; /* not enough data */
543 } 544 }
544 if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen))) 545 if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen)))
545 { 546 {
546 if (pp->state != PP_Init) 547 if (pp->state != PP_Init)
547 pp->state = PP_Error; 548 {
549 /* garbage not allowed */
550 pp->state = PP_Error;
551 }
552 else
553 {
554 /* skip over garbage (RFC 2046, 5.1.1) */
555 dash = memchr (buf, '-', pp->buffer_pos);
556 if (NULL == dash)
557 (*ioffptr) += pp->buffer_pos; /* skip entire buffer */
558 else
559 if (dash == buf)
560 (*ioffptr)++; /* at least skip one byte */
561 else
562 (*ioffptr) += dash - buf; /* skip to first possible boundary */
563 }
548 return MHD_NO; /* expected boundary */ 564 return MHD_NO; /* expected boundary */
549 } 565 }
550 /* remove boundary from buffer */ 566 /* remove boundary from buffer */
@@ -699,7 +715,7 @@ process_value_to_boundary (struct MHD_PostProcessor *pp,
699 { 715 {
700 while (newline + 4 < pp->buffer_pos) 716 while (newline + 4 < pp->buffer_pos)
701 { 717 {
702 r = memchr (&buf[newline], '\r', pp->buffer_pos - newline); 718 r = memchr (&buf[newline], '\r', pp->buffer_pos - newline - 4);
703 if (NULL == r) 719 if (NULL == r)
704 { 720 {
705 newline = pp->buffer_pos - 4; 721 newline = pp->buffer_pos - 4;
diff --git a/src/microhttpd/test_postprocessor.c b/src/microhttpd/test_postprocessor.c
index dd980506..ac3e2b91 100644
--- a/src/microhttpd/test_postprocessor.c
+++ b/src/microhttpd/test_postprocessor.c
@@ -1,10 +1,10 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff 3 (C) 2007,2013 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
7 by the Free Software Foundation; either version 2, or (at your 7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version. 8 option) any later version.
9 9
10 libmicrohttpd is distributed in the hope that it will be useful, but 10 libmicrohttpd is distributed in the hope that it will be useful, but
@@ -94,10 +94,12 @@ value_checker (void *cls,
94#if 0 94#if 0
95 fprintf (stderr, 95 fprintf (stderr,
96 "VC: `%s' `%s' `%s' `%s' `%.*s'\n", 96 "VC: `%s' `%s' `%s' `%s' `%.*s'\n",
97 key, filename, content_type, transfer_encoding, size, data); 97 key, filename, content_type, transfer_encoding,
98 (int) size,
99 data);
98#endif 100#endif
99 if ( (0 != off) && (0 == size) ) 101 if ( (0 != off) && (0 == size) )
100 return MHD_YES; 102 return MHD_YES;
101 if ((idx < 0) || 103 if ((idx < 0) ||
102 (want[idx] == NULL) || 104 (want[idx] == NULL) ||
103 (0 != strcmp (key, want[idx])) || 105 (0 != strcmp (key, want[idx])) ||
@@ -151,14 +153,53 @@ test_urlencoding ()
151 153
152 154
153static int 155static int
156test_multipart_garbage ()
157{
158 struct MHD_Connection connection;
159 struct MHD_HTTP_Header header;
160 struct MHD_PostProcessor *pp;
161 unsigned int want_off;
162 size_t size = strlen (FORM_DATA);
163 size_t splitpoint;
164 char xdata[size + 3];
165
166 /* fill in evil garbage at the beginning */
167 xdata[0] = '-';
168 xdata[1] = 'x';
169 xdata[2] = '\r';
170 memcpy (&xdata[3], FORM_DATA, size);
171 size += 3;
172
173 size = strlen (FORM_DATA);
174 for (splitpoint = 1; splitpoint < size; splitpoint++)
175 {
176 want_off = FORM_START;
177 memset (&connection, 0, sizeof (struct MHD_Connection));
178 memset (&header, 0, sizeof (struct MHD_HTTP_Header));
179 connection.headers_received = &header;
180 header.header = MHD_HTTP_HEADER_CONTENT_TYPE;
181 header.value =
182 MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x";
183 header.kind = MHD_HEADER_KIND;
184 pp = MHD_create_post_processor (&connection,
185 1024, &value_checker, &want_off);
186 MHD_post_process (pp, xdata, splitpoint);
187 MHD_post_process (pp, &xdata[splitpoint], size - splitpoint);
188 MHD_destroy_post_processor (pp);
189 if (want_off != FORM_END)
190 return (int) splitpoint;
191 }
192 return 0;
193}
194
195
196static int
154test_multipart_splits () 197test_multipart_splits ()
155{ 198{
156 struct MHD_Connection connection; 199 struct MHD_Connection connection;
157 struct MHD_HTTP_Header header; 200 struct MHD_HTTP_Header header;
158 struct MHD_PostProcessor *pp; 201 struct MHD_PostProcessor *pp;
159 unsigned int want_off; 202 unsigned int want_off;
160 int i;
161 int delta;
162 size_t size; 203 size_t size;
163 size_t splitpoint; 204 size_t splitpoint;
164 205
@@ -175,13 +216,8 @@ test_multipart_splits ()
175 header.kind = MHD_HEADER_KIND; 216 header.kind = MHD_HEADER_KIND;
176 pp = MHD_create_post_processor (&connection, 217 pp = MHD_create_post_processor (&connection,
177 1024, &value_checker, &want_off); 218 1024, &value_checker, &want_off);
178 i = 0; 219 MHD_post_process (pp, FORM_DATA, splitpoint);
179 delta = splitpoint; 220 MHD_post_process (pp, &FORM_DATA[splitpoint], size - splitpoint);
180 MHD_post_process (pp, &FORM_DATA[i], delta);
181 i += delta;
182 delta = 1 + size - i;
183 MHD_post_process (pp, &FORM_DATA[i], delta);
184 i += delta;
185 MHD_destroy_post_processor (pp); 221 MHD_destroy_post_processor (pp);
186 if (want_off != FORM_END) 222 if (want_off != FORM_END)
187 return (int) splitpoint; 223 return (int) splitpoint;
@@ -301,8 +337,9 @@ main (int argc, char *const *argv)
301{ 337{
302 unsigned int errorCount = 0; 338 unsigned int errorCount = 0;
303 339
304 errorCount += test_urlencoding ();
305 errorCount += test_multipart_splits (); 340 errorCount += test_multipart_splits ();
341 errorCount += test_multipart_garbage ();
342 errorCount += test_urlencoding ();
306 errorCount += test_multipart (); 343 errorCount += test_multipart ();
307 errorCount += test_nested_multipart (); 344 errorCount += test_nested_multipart ();
308 errorCount += test_empty_value (); 345 errorCount += test_empty_value ();