You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-cvs@httpd.apache.org by jo...@apache.org on 2003/04/24 22:17:18 UTC
cvs commit: httpd-apreq-2/t parsers.c Makefile.am env.c test_apreq.h testall.c
joes 2003/04/24 13:17:17
Modified: src apreq_parsers.c
t Makefile.am env.c test_apreq.h testall.c
Added: t parsers.c
Log:
Added parser.c tests; fixed some segfaults in the parsers.
Revision Changes Path
1.20 +51 -50 httpd-apreq-2/src/apreq_parsers.c
Index: apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- apreq_parsers.c 24 Apr 2003 15:02:49 -0000 1.19
+++ apreq_parsers.c 24 Apr 2003 20:17:17 -0000 1.20
@@ -425,16 +425,21 @@
parser->v.status = HDR_NAME;
for (e = APR_BRIGADE_FIRST(bb), nlen = glen = vlen = 0;
- ! APR_BUCKET_IS_EOS(e) && e != APR_BRIGADE_SENTINEL(bb);
- e = APR_BUCKET_NEXT(e))
+ e != APR_BRIGADE_SENTINEL(bb); e = APR_BUCKET_NEXT(e))
{
apr_size_t off = 0, dlen;
const char *data;
- apr_status_t s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
+ apr_status_t s;
+ if (APR_BUCKET_IS_EOS(e))
+ return parser->v.status = APR_EOF;
+
+ s = apr_bucket_read(e, &data, &dlen, APR_BLOCK_READ);
if ( s != APR_SUCCESS )
return s;
+ if (dlen == 0)
+ continue;
parse_hdr_bucket:
@@ -454,26 +459,25 @@
switch (data[off++]) {
case '\n':
- if (off < dlen) {
+ if (off < dlen)
apr_bucket_split(e, off);
- }
e = APR_BUCKET_NEXT(e);
- do apr_bucket_delete( APR_BRIGADE_FIRST(bb) );
- while (e != APR_BRIGADE_FIRST(bb));
+ do {
+ apr_bucket *f = APR_BRIGADE_FIRST(bb);
+ apr_bucket_delete(f);
+ } while (e != APR_BRIGADE_FIRST(bb));
return APR_SUCCESS;
case ':':
++glen;
- ++off;
parser->v.status = HDR_GAP;
goto parse_hdr_bucket;
default:
++nlen;
- ++off;
}
}
@@ -506,10 +510,8 @@
case HDR_VALUE:
while (off < dlen) {
- if (data[off++] != '\n')
- ++vlen;
- else {
- --vlen;
+ ++vlen;
+ if (data[off++] == '\n') {
parser->v.status = HDR_NEWLINE;
goto parse_hdr_bucket;
}
@@ -533,11 +535,8 @@
default:
/* can parse brigade now */
- if (off > 0) {
- apr_bucket_split(e, off - 1);
- e = APR_BUCKET_NEXT(e);
- }
-
+ if (off > 0)
+ apr_bucket_split(e, off);
s = split_header(pool, t, bb, nlen, glen, vlen);
if (s != APR_SUCCESS)
return s;
@@ -582,7 +581,7 @@
struct mfd_ctx {
void *hook_data;
- apreq_table_t *t;
+ apreq_parser_t *hdr_parser;
apr_bucket_brigade *bb;
const apr_strmatch_pattern *pattern;
char bdry[1];
@@ -604,27 +603,32 @@
const char *buf;
apr_status_t s;
-
if (APR_BUCKET_IS_EOS(e))
return APR_EOF;
+
s = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ);
if (s != APR_SUCCESS)
return s;
if (len == 0) {
+ apr_bucket *f = e;
e = APR_BUCKET_NEXT(e);
+ apr_bucket_delete(f);
continue;
}
if (strncmp(bdry + off, buf, MIN(len, blen - off)) == 0) {
if ( len >= blen - off ) {
/* complete match */
- apr_bucket_split(e, blen - off);
+ if (len > blen - off)
+ apr_bucket_split(e, blen - off);
e = APR_BUCKET_NEXT(e);
- do apr_bucket_delete( APR_BRIGADE_FIRST(in) );
- while (APR_BRIGADE_FIRST(in) != e);
+ do {
+ apr_bucket *f = APR_BRIGADE_FIRST(in);
+ apr_bucket_delete(f);
+ } while (APR_BRIGADE_FIRST(in) != e);
return APR_SUCCESS;
}
@@ -635,12 +639,11 @@
}
else if (off > 0) {
/* prior (partial) strncmp failed, restart */
- apr_bucket *f;
do {
- f = APR_BRIGADE_FIRST(in);
+ apr_bucket *f = APR_BRIGADE_FIRST(in);
APR_BUCKET_REMOVE(f);
APR_BRIGADE_INSERT_TAIL(out, f);
- } while (e != f);
+ } while (e != APR_BRIGADE_FIRST(in));
off = 0;
}
@@ -689,7 +692,7 @@
while (apr_isspace(*loc) && loc - *line > nlen)
--loc;
- loc -= nlen;
+ loc -= nlen - 1;
if (strncasecmp(loc, name, nlen) != 0)
return APR_NOTFOUND;
@@ -708,7 +711,7 @@
while (apr_isspace(*loc) && loc - *line > nlen)
--loc;
- loc -= nlen;
+ loc -= nlen - 1;
if (strncasecmp(loc, name, nlen) != 0)
return APR_NOTFOUND;
@@ -720,7 +723,6 @@
++*val;
in_quotes = 1;
}
-
for(loc = *val; *loc; ++loc) {
switch (*loc) {
case ' ':
@@ -773,7 +775,7 @@
memcpy(ctx->bdry, CRLF "--", 4);
s = nextval(&ct, "boundary", &bdry, &blen);
-
+
if (s != APR_SUCCESS)
return s;
@@ -783,9 +785,7 @@
memcpy(ctx->bdry + 4, bdry, blen);
ctx->bdry[4 + blen] = 0;
ctx->pattern = apr_strmatch_precompile(pool,ctx->bdry,1);
-
- APR_BRIGADE_INSERT_HEAD(bb,
- apr_bucket_immortal_create(crlf,2,bb->bucket_alloc));
+ ctx->hdr_parser = apreq_make_parser(pool,"",NULL,NULL,NULL);
if (ctx->bb == NULL)
ctx->bb = apr_brigade_create(pool, bb->bucket_alloc);
@@ -802,7 +802,7 @@
case MFD_INIT:
{
apr_status_t s;
- s = split_on_bdry(pool, ctx->bb, bb, ctx->pattern, ctx->bdry);
+ s = split_on_bdry(pool, ctx->bb, bb, NULL, ctx->bdry + 2);
if (s != APR_SUCCESS)
return s;
@@ -819,30 +819,32 @@
parser->v.status = MFD_HEADER;
apr_brigade_cleanup(ctx->bb);
- ctx->t = NULL;
+ ctx->hdr_parser->out = NULL;
}
/* fall through */
case MFD_HEADER:
{
- apreq_parser_t par = {0};
apr_status_t s;
const char *cd, *name, *filename;
apr_size_t nlen, flen;
+ apreq_table_t *t;
- if (ctx->t == NULL)
- ctx->t = apreq_make_table(pool, APREQ_NELTS);
+ if (ctx->hdr_parser->out == NULL)
+ ctx->hdr_parser->out = apreq_make_table(pool, APREQ_NELTS);
- par.out = (void *)ctx->t;
- s = apreq_parse_headers(pool, bb, &par);
+ s = apreq_parse_headers(pool, bb, ctx->hdr_parser);
if (s != APR_SUCCESS)
- return s;
+ if (s == APR_EOF)
+ return APR_SUCCESS;
+ else
+ return s;
- cd = apreq_table_get(ctx->t, "Content-Disposition");
+ t = ctx->hdr_parser->out;
+ cd = apreq_table_get(t, "Content-Disposition");
- if (cd == NULL ||
- nextval(&cd, "form-data", &name, &nlen) != APR_SUCCESS) {
+ if (cd == NULL) {
parser->v.status = MFD_ERROR;
return APR_BADARG;
}
@@ -866,7 +868,7 @@
else {
apreq_param_t *param = apreq_make_param(pool, name, nlen,
filename, flen);
- param->info = ctx->t;
+ param->info = t;
param->bb = apr_brigade_create(pool,
apr_bucket_alloc_create(pool));
@@ -902,12 +904,12 @@
parser->v.status = MFD_ERROR;
return s;
}
-
+ len = off;
param = apr_palloc(pool, len + sizeof *param);
param->charset = APREQ_CHARSET;
param->language = NULL;
param->bb = NULL;
- param->info = ctx->t;
+ param->info = ctx->hdr_parser->out;
v = ¶m->v;
v->name = name;
@@ -915,7 +917,7 @@
apr_brigade_flatten(ctx->bb, v->data, &len);
v->size = len;
v->data[v->size] = 0;
-
+ apreq_table_add(req->body, v);
parser->v.status = MFD_NEXTLINE;
goto mfd_parse_brigade;
@@ -938,7 +940,7 @@
arr = apreq_table_elts(req->body);
param = apreq_value_to_param(*(apreq_value_t **)
- (arr->elts + (arr->elt_size * arr->nelts-1)));
+ (arr->elts + (arr->elt_size * (arr->nelts-1))));
switch (s) {
@@ -960,7 +962,6 @@
}
else
APR_BRIGADE_CONCAT(param->bb, ctx->bb);
-
parser->v.status = MFD_NEXTLINE;
goto mfd_parse_brigade;
1.6 +1 -1 httpd-apreq-2/t/Makefile.am
Index: Makefile.am
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Makefile.am 21 Apr 2003 20:16:24 -0000 1.5
+++ Makefile.am 24 Apr 2003 20:17:17 -0000 1.6
@@ -2,7 +2,7 @@
LIBS = -L../src
noinst_LIBRARIES = libapreq_tests.a
-libapreq_tests_a_SOURCES = CuTest.c env.c tables.c cookie.c params.c
+libapreq_tests_a_SOURCES = CuTest.c env.c tables.c cookie.c params.c parsers.c
libapreq_tests_a_LIBADD = ../src/libapreq.la
check_PROGRAMS = testall
1.6 +1 -1 httpd-apreq-2/t/env.c
Index: env.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/env.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- env.c 21 Apr 2003 20:16:24 -0000 1.5
+++ env.c 24 Apr 2003 20:17:17 -0000 1.6
@@ -75,7 +75,7 @@
static const char *env_in(void *ctx, const char *name)
{
- return NULL;
+ return ctx;
}
static apr_status_t env_out(void *ctx, const char *name, char *value)
1.4 +1 -0 httpd-apreq-2/t/test_apreq.h
Index: test_apreq.h
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/test_apreq.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- test_apreq.h 21 Apr 2003 20:16:24 -0000 1.3
+++ test_apreq.h 24 Apr 2003 20:17:17 -0000 1.4
@@ -70,6 +70,7 @@
CuSuite *testcookie(void);
CuSuite *testenv(void);
CuSuite *testparam(void);
+CuSuite *testparser(void);
/* Assert that RV is an APR_SUCCESS value; else fail giving strerror
* for RV and CONTEXT message. */
1.6 +1 -0 httpd-apreq-2/t/testall.c
Index: testall.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/t/testall.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- testall.c 21 Apr 2003 20:16:24 -0000 1.5
+++ testall.c 24 Apr 2003 20:17:17 -0000 1.6
@@ -81,6 +81,7 @@
{"tables", testtable},
{"cookies", testcookie},
{"params", testparam},
+ {"parsers", testparser},
{"LastTest", NULL}
};
1.1 httpd-apreq-2/t/parsers.c
Index: parsers.c
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include "apreq_env.h"
#include "test_apreq.h"
#include "apreq.h"
#include "apreq_params.h"
#include "apr_strings.h"
#include "apreq_parsers.h"
#define CRLF "\015\012"
static char url_data[] = "alpha=one&beta=two;omega=last";
static char form_data[] =
"--AaB03x" CRLF
"content-disposition: form-data; name=\"field1\"" CRLF
"content-type: text/plain;charset=windows-1250" CRLF
"content-transfer-encoding: quoted-printable" CRLF CRLF
"Joe owes =80100." CRLF
"--AaB03x" CRLF
"content-disposition: form-data; name=\"pics\"; filename=\"file1.txt\"" CRLF
"Content-Type: text/plain" CRLF CRLF
"... contents of file1.txt ..." CRLF
"--AaB03x--" CRLF;
static void parse_urlencoded(CuTest *tc)
{
const char *val;
apreq_request_t *r = apreq_request(APREQ_URL_ENCTYPE,"");
apr_bucket_brigade *bb = apr_brigade_create(p,
apr_bucket_alloc_create(p));
CuAssertPtrNotNull(tc, r);
APR_BRIGADE_INSERT_HEAD(bb,
apr_bucket_immortal_create(url_data,strlen(url_data),
bb->bucket_alloc));
APR_BRIGADE_INSERT_TAIL(bb,
apr_bucket_eos_create(bb->bucket_alloc));
CuAssertIntEquals(tc, APR_INCOMPLETE, r->v.status);
while (apreq_parse(r, bb) == APR_INCOMPLETE)
;
CuAssertIntEquals(tc, APR_SUCCESS, r->v.status);
val = apreq_table_get(r->body,"alpha");
CuAssertStrEquals(tc, "one", val);
val = apreq_table_get(r->body,"beta");
CuAssertStrEquals(tc, "two", val);
val = apreq_table_get(r->body,"omega");
CuAssertStrEquals(tc, "last", val);
}
static void parse_multipart(CuTest *tc)
{
const char *val;
apreq_request_t *r = apreq_request(APREQ_MFD_ENCTYPE
"; boundary=\"AaB03x\"" ,"");
apr_bucket_brigade *bb = apr_brigade_create(p,
apr_bucket_alloc_create(p));
CuAssertPtrNotNull(tc, r);
APR_BRIGADE_INSERT_HEAD(bb,
apr_bucket_immortal_create(form_data,strlen(form_data),
bb->bucket_alloc));
APR_BRIGADE_INSERT_TAIL(bb,
apr_bucket_eos_create(bb->bucket_alloc));
CuAssertIntEquals(tc, APR_INCOMPLETE, r->v.status);
while (apreq_parse(r, bb) == APR_INCOMPLETE)
;
CuAssertIntEquals(tc, APR_SUCCESS, r->v.status);
CuAssertPtrNotNull(tc, r->body);
CuAssertIntEquals(tc, 2, apreq_table_nelts(r->body));
val = apreq_table_get(r->body,"field1");
CuAssertStrEquals(tc, "Joe owes =80100.", val);
val = apreq_table_get(r->body,"pics");
CuAssertStrEquals(tc, "file1.txt", val);
}
CuSuite *testparser(void)
{
CuSuite *suite = CuSuiteNew("Parsers");
SUITE_ADD_TEST(suite, parse_urlencoded);
SUITE_ADD_TEST(suite, parse_multipart);
return suite;
}