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);