libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 3fb38e694808965356d6a02447d186107701fa24
parent e524263be242e774d76377b04de9b033bd149d2e
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 30 Oct 2013 08:35:28 +0000

-fix post processor, expanded test suite to cover garbage before payload

Diffstat:
MChangeLog | 4++++
Msrc/microhttpd/postprocessor.c | 22+++++++++++++++++++---
Msrc/microhttpd/test_postprocessor.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++--------------
3 files changed, 74 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,7 @@ +Wed Oct 30 09:34:20 CET 2013 + Fixing issue in PostProcessor when getting partial boundary + at the beginning, expanding test suite. -CG + Sun Oct 27 15:19:44 CET 2013 Implementing faster processing of upload data in multipart encoding (thanks to performance analysis by Adam Homolya). -CG diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c @@ -533,18 +533,34 @@ find_boundary (struct MHD_PostProcessor *pp, enum PP_State next_state, enum PP_State next_dash_state) { char *buf = (char *) &pp[1]; + const char *dash; if (pp->buffer_pos < 2 + blen) { if (pp->buffer_pos == pp->buffer_size) pp->state = PP_Error; /* out of memory */ - ++(*ioffptr); + // ++(*ioffptr); return MHD_NO; /* not enough data */ } if ((0 != memcmp ("--", buf, 2)) || (0 != memcmp (&buf[2], boundary, blen))) { if (pp->state != PP_Init) - pp->state = PP_Error; + { + /* garbage not allowed */ + pp->state = PP_Error; + } + else + { + /* skip over garbage (RFC 2046, 5.1.1) */ + dash = memchr (buf, '-', pp->buffer_pos); + if (NULL == dash) + (*ioffptr) += pp->buffer_pos; /* skip entire buffer */ + else + if (dash == buf) + (*ioffptr)++; /* at least skip one byte */ + else + (*ioffptr) += dash - buf; /* skip to first possible boundary */ + } return MHD_NO; /* expected boundary */ } /* remove boundary from buffer */ @@ -699,7 +715,7 @@ process_value_to_boundary (struct MHD_PostProcessor *pp, { while (newline + 4 < pp->buffer_pos) { - r = memchr (&buf[newline], '\r', pp->buffer_pos - newline); + r = memchr (&buf[newline], '\r', pp->buffer_pos - newline - 4); if (NULL == r) { newline = pp->buffer_pos - 4; diff --git a/src/microhttpd/test_postprocessor.c b/src/microhttpd/test_postprocessor.c @@ -1,10 +1,10 @@ /* This file is part of libmicrohttpd - (C) 2007 Christian Grothoff + (C) 2007,2013 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 - by the Free Software Foundation; either version 2, or (at your + by the Free Software Foundation; either version 3, or (at your option) any later version. libmicrohttpd is distributed in the hope that it will be useful, but @@ -94,10 +94,12 @@ value_checker (void *cls, #if 0 fprintf (stderr, "VC: `%s' `%s' `%s' `%s' `%.*s'\n", - key, filename, content_type, transfer_encoding, size, data); + key, filename, content_type, transfer_encoding, + (int) size, + data); #endif if ( (0 != off) && (0 == size) ) - return MHD_YES; + return MHD_YES; if ((idx < 0) || (want[idx] == NULL) || (0 != strcmp (key, want[idx])) || @@ -151,14 +153,53 @@ test_urlencoding () static int +test_multipart_garbage () +{ + struct MHD_Connection connection; + struct MHD_HTTP_Header header; + struct MHD_PostProcessor *pp; + unsigned int want_off; + size_t size = strlen (FORM_DATA); + size_t splitpoint; + char xdata[size + 3]; + + /* fill in evil garbage at the beginning */ + xdata[0] = '-'; + xdata[1] = 'x'; + xdata[2] = '\r'; + memcpy (&xdata[3], FORM_DATA, size); + size += 3; + + size = strlen (FORM_DATA); + for (splitpoint = 1; splitpoint < size; splitpoint++) + { + want_off = FORM_START; + memset (&connection, 0, sizeof (struct MHD_Connection)); + memset (&header, 0, sizeof (struct MHD_HTTP_Header)); + connection.headers_received = &header; + header.header = MHD_HTTP_HEADER_CONTENT_TYPE; + header.value = + MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA ", boundary=AaB03x"; + header.kind = MHD_HEADER_KIND; + pp = MHD_create_post_processor (&connection, + 1024, &value_checker, &want_off); + MHD_post_process (pp, xdata, splitpoint); + MHD_post_process (pp, &xdata[splitpoint], size - splitpoint); + MHD_destroy_post_processor (pp); + if (want_off != FORM_END) + return (int) splitpoint; + } + return 0; +} + + +static int test_multipart_splits () { struct MHD_Connection connection; struct MHD_HTTP_Header header; struct MHD_PostProcessor *pp; unsigned int want_off; - int i; - int delta; size_t size; size_t splitpoint; @@ -175,13 +216,8 @@ test_multipart_splits () header.kind = MHD_HEADER_KIND; pp = MHD_create_post_processor (&connection, 1024, &value_checker, &want_off); - i = 0; - delta = splitpoint; - MHD_post_process (pp, &FORM_DATA[i], delta); - i += delta; - delta = 1 + size - i; - MHD_post_process (pp, &FORM_DATA[i], delta); - i += delta; + MHD_post_process (pp, FORM_DATA, splitpoint); + MHD_post_process (pp, &FORM_DATA[splitpoint], size - splitpoint); MHD_destroy_post_processor (pp); if (want_off != FORM_END) return (int) splitpoint; @@ -301,8 +337,9 @@ main (int argc, char *const *argv) { unsigned int errorCount = 0; - errorCount += test_urlencoding (); errorCount += test_multipart_splits (); + errorCount += test_multipart_garbage (); + errorCount += test_urlencoding (); errorCount += test_multipart (); errorCount += test_nested_multipart (); errorCount += test_empty_value ();