stas        2003/02/06 18:30:53

  Modified:    src/modules/perl modperl_filter.c
  Log:
  we have no choice but to truncate wb->outbuf to the size of 'len'. All
  kind of weird problems pop-up when the previous request was proper and the
  current request has messed up with headers, because
  modperl_cgi_header_parse (actually the ap_scan_script_header_err_strs)
  will get things messed up because it expects a buffer with real data only.
  
  Revision  Changes    Path
  1.50      +24 -23    modperl-2.0/src/modules/perl/modperl_filter.c
  
  Index: modperl_filter.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- modperl_filter.c  7 Feb 2003 00:07:42 -0000       1.49
  +++ modperl_filter.c  7 Feb 2003 02:30:52 -0000       1.50
  @@ -8,11 +8,28 @@
       apr_bucket_alloc_t *ba = (*wb->filters)->c->bucket_alloc;
       apr_bucket_brigade *bb;
       apr_bucket *bucket;
  -
  +    const char *work_buf = buf;
  +    
       if (wb->header_parse) {
           request_rec *r = wb->r;
           const char *bodytext = NULL;
  -        int status = modperl_cgi_header_parse(r, (char *)buf, &bodytext);
  +        int status;
  +        /*
  +         * since wb->outcnt is persistent between requests, if the
  +         * current response is shorter than the size of wb->outcnt
  +         * it may include data from the previous request at the
  +         * end. When this function receives a pointer to
  +         * wb->outbuf as 'buf', modperl_cgi_header_parse may
  +         * return that irrelevant data as part of 'bodytext'. So
  +         * to avoid this risk, we create a new buffer of size 'len'
  +         * XXX: if buf wasn't 'const char *buf' we could simply do
  +         * buf[len] = '\0'
  +         */
  +        if (len < strlen(buf)) {
  +            work_buf = (char *)apr_pcalloc(wb->pool, sizeof(char*)*len);
  +            memcpy((void*)work_buf, buf, len);
  +        }
  +        status = modperl_cgi_header_parse(r, (char *)work_buf, &bodytext);
   
           wb->header_parse = 0; /* only once per-request */
   
  @@ -26,32 +43,16 @@
               /* XXX: bodytext == NULL here */
               return status;
           }
  -
  -        if (!bodytext) {
  +        else if (!bodytext) {
               return APR_SUCCESS;
           }
  -        else {
  -            len -= (bodytext - buf);
  -            buf = bodytext;
  -            /*
  -             * since wb->outbuf is persistent between requests, if the
  -             * current response is shorter than the size of wb->outbuf
  -             * it may include data from the previous request at the
  -             * end. When this function receives a pointer to
  -             * wb->outbuf as 'buf', modperl_cgi_header_parse may
  -             * return that irrelevant data as part of 'bodytext'. So
  -             * to avoid this risk, we check whether there is any real
  -             * data to send and if not return.
  -             */
  -            if (!len) {
  -                return APR_SUCCESS;
  -            }
  -        }
  -        
  +
  +        len -= (bodytext - work_buf);
  +        work_buf = bodytext;
       }
   
       bb = apr_brigade_create(wb->pool, ba);
  -    bucket = apr_bucket_transient_create(buf, len, ba);
  +    bucket = apr_bucket_transient_create(work_buf, len, ba);
       APR_BRIGADE_INSERT_TAIL(bb, bucket);
   
       MP_TRACE_f(MP_FUNC, "buffer length=%d\n", len);
  
  
  


Reply via email to