libmicrohttpd

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

commit a0cc83b7c2325dfceec0851c2046148059c84619
parent 43f13d6f3b84b693f64b015b9242e3fcf59ec39b
Author: Christian Grothoff <christian@grothoff.org>
Date:   Fri, 23 May 2008 23:07:41 +0000

fixing postprocessor issues and adding testcase

Diffstat:
MChangeLog | 4++++
Msrc/daemon/Makefile.am | 7+++++++
Msrc/daemon/postprocessor.c | 23++++++++++++++---------
Asrc/daemon/postprocessor_large_test.c | 109+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 134 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,3 +1,7 @@ +Fri May 23 16:54:41 MDT 2008 + Fixed issue with postprocessor not handling URI-encoded + values of more than 1024 bytes correctly. -CG + Mon May 5 09:18:29 MDT 2008 Fixed date header (was off by 1900 years). -JP diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am @@ -25,6 +25,7 @@ libmicrohttpd_la_SOURCES = \ check_PROGRAMS = \ postprocessor_test \ + postprocessor_large_test \ daemon_test TESTS = $(check_PROGRAMS) @@ -38,3 +39,9 @@ postprocessor_test_SOURCES = \ postprocessor_test.c postprocessor_test_LDADD = \ $(top_builddir)/src/daemon/libmicrohttpd.la + + +postprocessor_large_test_SOURCES = \ + postprocessor_large_test.c +postprocessor_large_test_LDADD = \ + $(top_builddir)/src/daemon/libmicrohttpd.la diff --git a/src/daemon/postprocessor.c b/src/daemon/postprocessor.c @@ -361,9 +361,10 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, (post_data[amper + poff] != '\n') && (post_data[amper + poff] != '\r')) amper++; - end_of_value_found = ( (post_data[amper + poff] == '&') || - (post_data[amper + poff] == '\n') || - (post_data[amper + poff] == '\r') ); + end_of_value_found = ( (amper + poff < post_data_len) && + ( (post_data[amper + poff] == '&') || + (post_data[amper + poff] == '\n') || + (post_data[amper + poff] == '\r') ) ); /* compute delta, the maximum number of bytes that we will be able to process right now (either amper-limited of xbuf-size limited) */ delta = amper; @@ -417,12 +418,16 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, if (end_of_value_found) { /* we found the end of the value! */ - pp->state = PP_Init; - poff++; /* skip '&' or new-lines */ - - if ((post_data[poff - 1] == '\n') || - (post_data[poff - 1] == '\r')) - pp->state = PP_ExpectNewLine; + if ((post_data[poff] == '\n') || + (post_data[poff] == '\r')) + { + pp->state = PP_ExpectNewLine; + } + else + { + poff++; /* skip '&' */ + pp->state = PP_Init; + } } break; case PP_ExpectNewLine: diff --git a/src/daemon/postprocessor_large_test.c b/src/daemon/postprocessor_large_test.c @@ -0,0 +1,109 @@ +/* + This file is part of libmicrohttpd + (C) 2008 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 + option) any later version. + + libmicrohttpd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libmicrohttpd; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +/** + * @file postprocessor_large_test.c + * @brief Testcase with very large input for postprocessor + * @author Christian Grothoff + */ + +#include "config.h" +#include "microhttpd.h" +#include "internal.h" +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +#ifndef WINDOWS +#include <unistd.h> +#endif + +static int +value_checker (void *cls, + enum MHD_ValueKind kind, + const char *key, + const char *filename, + const char *content_type, + const char *transfer_encoding, + const char *data, size_t off, size_t size) +{ + unsigned int *pos = cls; +#if 0 + fprintf (stderr, + "VC: %u %u `%s' `%s' `%s' `%s' `%.*s'\n", + off, size, + key, filename, content_type, transfer_encoding, size, data); +#endif + if (size == 0) + return MHD_YES; + *pos += size; + return MHD_YES; + +} + + +static int +test_simple_large () +{ + struct MHD_Connection connection; + struct MHD_HTTP_Header header; + struct MHD_PostProcessor *pp; + int i; + int delta; + size_t size; + char data[102400]; + unsigned int pos; + + pos = 0; + memset (data, 'A', sizeof(data)); + memcpy (data, "key=", 4); + data[sizeof(data)-1] = '\0'; + 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_FORM_URLENCODED; + header.kind = MHD_HEADER_KIND; + pp = MHD_create_post_processor (&connection, + 1024, &value_checker, &pos); + i = 0; + size = strlen (data); + while (i < size) + { + delta = 1 + random () % (size - i); + MHD_post_process (pp, &data[i], delta); + i += delta; + } + MHD_destroy_post_processor (pp); + if (pos != sizeof(data) - 5) /* minus 0-termination and 'key=' */ + return 1; + return 0; +} + +int +main (int argc, char *const *argv) +{ + unsigned int errorCount = 0; + + errorCount += test_simple_large (); + if (errorCount != 0) + fprintf (stderr, "Error (code: %u)\n", errorCount); + return errorCount != 0; /* 0 == pass */ +}