From: Jeff Trawick Date: Thu, 7 Jun 2001 01:24:44 +0000 (+0000) Subject: implement Ryan's suggested fix for buckets associated with a subrequest X-Git-Tag: 2.0.19~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edc450c8ac161c88a95c2fdb7ecd186a94d6f76c;p=thirdparty%2Fapache%2Fhttpd.git implement Ryan's suggested fix for buckets associated with a subrequest having private data in the wrong (i.e., subrequest) pool, leading to a segfault later in processing the main request in the patch posted on new-httpd, the temporary brigade was allocated from the connection pool; the committed code allocates the brigade from the main-request pool, as suggested by Ian Holsman git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@89284 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/request.c b/server/request.c index 4e2e1edbc58..dc222fb4a65 100644 --- a/server/request.c +++ b/server/request.c @@ -808,7 +808,40 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f, apr_bucket *e = APR_BRIGADE_LAST(bb); if (APR_BUCKET_IS_EOS(e)) { + apr_bucket_brigade *tmpbb; + apr_bucket_delete(e); + + if (!APR_BRIGADE_EMPTY(bb)) { /* avoid brigade create/destroy */ + + /* We need to be certain that any data in a bucket is valid + * after the subrequest pool is cleared. + */ + tmpbb = apr_brigade_create(f->r->main->pool); + + APR_BRIGADE_FOREACH(e, bb) { + const char *str; + apr_size_t n; + apr_status_t rv; + + rv = apr_bucket_read(e, &str, &n, APR_BLOCK_READ); + /* XXX handle rv! */ + + /* This apr_brigade_write does not use a flush function + because we assume that we will not write enough data + into it to cause a flush. However, if we *do* write + "too much", then we could end up with transient + buckets which would suck. This works for now, but is + a bit shaky if changes are made to some of the + buffering sizes. Let's do an assert to prevent + potential future problems... */ + AP_DEBUG_ASSERT(AP_MIN_BYTES_TO_WRITE <= + APR_BUCKET_BUFF_SIZE); + apr_brigade_write(tmpbb, NULL, NULL, str, n); + } + apr_brigade_destroy(bb); + bb = tmpbb; + } } return ap_pass_brigade(f->next, bb); }