You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apreq-dev@httpd.apache.org by Jean-François Meessen <jf...@n-tech.be> on 2004/06/26 01:53:41 UTC
Found bug in multipart parser
Hi,
Needing Apache::Upload for an intranet application I developped at Alcatel
Bell. I discovered a bug preventing people using Netscape 7 to upload some
files (e.g. PDF documents)
In the parser function split_on_bdry, if a partial match is detected just
before a bucket boundary and a real boundary just after it, the parser fails
to detect it.
If the boundary string is for example \r\n----------123456 and the form data
contains:
The end of the file content...\r\n[BUCKET BOUNDARY]\r\n----------123456
The \r\n before bucket boundary will be a partial match and the following \r\n
will be interpreted as a mismatch (because the first 2 chars have already
been matched). In this case, the parser will not detect the boundary.
It seems that using Netscape 7, in some cases a bucket boundary is induced
just after the file content. And PDF files are terminated by a CR (\015) that
matches the first byte of boundary.
Here is the correction I made and the unit test improvement to check it:
diff -u -r1.49 apreq_parsers.c
--- src/apreq_parsers.c 21 Jun 2004 17:49:18 -0000 1.49
+++ src/apreq_parsers.c 25 Jun 2004 21:29:24 -0000
@@ -668,7 +668,8 @@
continue;
}
- if (strncmp(bdry + off, buf, MIN(len, blen - off)) == 0) {
+mfd_split_bdry_restart:
+ if (strncmp(bdry + off, buf, MIN(len, blen - off)) == 0) {
if ( len >= blen - off ) {
/* complete match */
if (len > blen - off)
@@ -695,6 +696,7 @@
APR_BRIGADE_INSERT_TAIL(out, f);
} while (e != APR_BRIGADE_FIRST(in));
off = 0;
+ goto mfd_split_bdry_restart;
}
if (pattern != NULL && len >= blen) {
@@ -1071,7 +1073,7 @@
param->bb, ctx->bb);
if (param->v.status != APR_SUCCESS)
- return s;
+ return param->v.status;
ctx->status = MFD_NEXTLINE;
goto mfd_parse_brigade;
===================================================================
diff -u -r1.14 parsers.c
--- t/parsers.c 19 Jun 2004 20:03:59 -0000 1.14
+++ t/parsers.c 25 Jun 2004 21:30:11 -0000
@@ -32,7 +32,7 @@
"--AaB03x" CRLF
"content-disposition: form-data; name=\"pics\"; filename=\"file1.txt\"" CRLF
"Content-Type: text/plain" CRLF CRLF
-"... contents of file1.txt ..." CRLF
+"... contents of file1.txt ..." CRLF CRLF
"--AaB03x--" CRLF;
extern apr_bucket_brigade *bb;
@@ -120,8 +120,8 @@
t = apreq_value_to_param(apreq_strtoval(val))->info;
bb = apreq_value_to_param(apreq_strtoval(val))->bb;
apr_brigade_pflatten(bb, (char **)&val, &len, p);
- CuAssertIntEquals(tc,strlen("... contents of file1.txt ..."), len);
- CuAssertStrNEquals(tc,"... contents of file1.txt ...", val, len);
+ CuAssertIntEquals(tc,strlen("... contents of file1.txt ..." CRLF),
len);
+ CuAssertStrNEquals(tc,"... contents of file1.txt ..." CRLF, val,
len);
val = apr_table_get(t, "content-type");
CuAssertStrEquals(tc, "text/plain", val);
}
I also discovered that an error status was not returned correctly and fixed it
in the patch.
I hope it will help
Jean-François
--
MEESSEN Jean-François
Rue Baron de Castro, 61/1
1040 Brussels
BELGIUM
Re: Found bug in multipart parser
Posted by Joe Schaefer <jo...@sunstarsys.com>.
Jean-François Meessen <jf...@n-tech.be> writes:
[...]
> In the parser function split_on_bdry, if a partial match is detected just
> before a bucket boundary and a real boundary just after it, the parser
> fails to detect it. If the boundary string is for example
> \r\n----------123456 and the form data contains:
> The end of the file content...\r\n[BUCKET BOUNDARY]\r\n----------123456
> The \r\n before bucket boundary will be a partial match and the
> following \r\n will be interpreted as a mismatch (because the first 2
> chars have already been matched). In this case, the parser will not
> detect the boundary.
Thanks alot! Your patch looks correct to me, although there's
another way to fix apreq_parsers.c without the gotos:
Index: src/apreq_parsers.c
===================================================================
RCS file: /home/cvs/httpd-apreq-2/src/apreq_parsers.c,v
retrieving revision 1.49
diff -u -r1.49 apreq_parsers.c
--- src/apreq_parsers.c 21 Jun 2004 17:49:18 -0000 1.49
+++ src/apreq_parsers.c 26 Jun 2004 00:49:30 -0000
@@ -711,7 +711,7 @@
else
idx = apreq_index(buf, len, bdry, blen, APREQ_MATCH_PARTIAL);
- if (idx > 0)
+ if (idx >= 0)
apr_bucket_split(e, idx);
APR_BUCKET_REMOVE(e);
It's a simpler patch, but is less efficient than yours
because we're basically wasting an extra pattern match
and an empty bucket creation instead of just jumping
back to the start.
[...]
> I also discovered that an error status was not returned correctly
> and fixed it in the patch.
>
> I hope it will help
Absolutely- thanks!
--
Joe Schaefer