diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-10-30 08:35:28 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-10-30 08:35:28 +0000 |
commit | 3fb38e694808965356d6a02447d186107701fa24 (patch) | |
tree | 0442c555f8e27afe9c5ce7e4b34412c797a8b735 | |
parent | e524263be242e774d76377b04de9b033bd149d2e (diff) | |
download | libmicrohttpd-3fb38e694808965356d6a02447d186107701fa24.tar.gz libmicrohttpd-3fb38e694808965356d6a02447d186107701fa24.zip |
-fix post processor, expanded test suite to cover garbage before payload
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/microhttpd/postprocessor.c | 22 | ||||
-rw-r--r-- | src/microhttpd/test_postprocessor.c | 65 |
3 files changed, 74 insertions, 17 deletions
@@ -1,3 +1,7 @@ | |||
1 | Wed 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 | |||
1 | Sun Oct 27 15:19:44 CET 2013 | 5 | Sun 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 | ||
153 | static int | 155 | static int |
156 | test_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 | |||
196 | static int | ||
154 | test_multipart_splits () | 197 | test_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 (); |