You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by gr...@apache.org on 2001/11/02 21:21:44 UTC
cvs commit: httpd-2.0/modules/http http_protocol.c
gregames 01/11/02 12:21:44
Modified: modules/http http_protocol.c
Log:
prevent loops & seg faults when GETs have chunked bodies.
Revision Changes Path
1.375 +18 -3 httpd-2.0/modules/http/http_protocol.c
Index: http_protocol.c
===================================================================
RCS file: /home/cvs/httpd-2.0/modules/http/http_protocol.c,v
retrieving revision 1.374
retrieving revision 1.375
diff -u -r1.374 -r1.375
--- http_protocol.c 2001/10/16 01:04:08 1.374
+++ http_protocol.c 2001/11/02 20:21:44 1.375
@@ -90,6 +90,8 @@
#include "util_charset.h"
#include "util_ebcdic.h"
+#include <limits.h> /* for INT_MAX */
+
#include "mod_core.h"
#if APR_HAVE_STDARG_H
@@ -580,6 +582,7 @@
if ((ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) &&
ctx->remaining < *readbytes) {
*readbytes = ctx->remaining;
+ AP_DEBUG_ASSERT(*readbytes); /* shouldn't be in getline mode */
}
rv = ap_get_brigade(f->next, b, mode, readbytes);
@@ -1276,6 +1279,7 @@
max_body = ap_get_limit_req_body(r);
if (max_body && (r->remaining > max_body)) {
+ /* XXX shouldn't we enforce this for chunked encoding too? */
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
"Request content-length of %s is larger than "
"the configured limit of %" APR_OFF_T_FMT, lenp, max_body);
@@ -1365,15 +1369,26 @@
apr_status_t rv;
apr_bucket *b, *old;
const char *tempbuf;
+ apr_off_t len_read;
core_request_config *req_cfg =
(core_request_config *)ap_get_module_config(r->request_config,
&core_module);
apr_bucket_brigade *bb = req_cfg->bb;
+ if (r->remaining) {
+ len_read = r->remaining; /* Content-Length header, probably */
+ }
+ else {
+ len_read = INT_MAX; /* Transfer-Encoding: chunked */
+ }
+
+ if (len_read > bufsiz) {
+ /* limit the resources we use for heap buckets etc */
+ len_read = bufsiz;
+ }
+
/* read until we get a non-empty brigade */
while (APR_BRIGADE_EMPTY(bb)) {
- apr_off_t len_read;
- len_read = r->remaining;
if (ap_get_brigade(r->input_filters, bb, AP_MODE_BLOCKING,
&len_read) != APR_SUCCESS) {
/* if we actually fail here, we want to just return and
@@ -1383,7 +1398,7 @@
apr_brigade_destroy(bb);
return -1;
}
- r->remaining -= len_read;
+ r->remaining -= len_read; /* XXX goes negative w/chunking */
}
b = APR_BRIGADE_FIRST(bb);