From: Ruediger Pluem Date: Thu, 10 Dec 2009 20:18:05 +0000 (+0000) Subject: * Ensure that the new table values are allocated from the pool of the main X-Git-Tag: 2.3.5~93 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=140031be517115ad1660a9cd09dc81c2f7d7e1aa;p=thirdparty%2Fapache%2Fhttpd.git * Ensure that the new table values are allocated from the pool of the main request as they might be added to the header tables of the main request. Otherwise these values might become invalid once the subrequest and its pool gets destroyed. PR: 48359 Submitted by: rpluem, niq Reviewed by: niq git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@889408 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index f25b7972ac9..aa163833273 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.5 + *) mod_headers: Ensure that changes to the main request remain valid when + the subrequest is destroyed. PR 48359 [Nick Kew, Ruediger Pluem] + *) Core HTTP: disable keepalive when the Client has sent Expect: 100-continue but we respond directly with a non-100 response. diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index c9c73c7db94..2554681042f 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -543,7 +543,7 @@ static const char *header_cmd(cmd_parms *cmd, void *indirconf, * Concatenate the return from each handler into one string that is * returned from this call. */ -static char* process_tags(header_entry *hdr, request_rec *r) +static char* process_tags(header_entry *hdr, request_rec *r, request_rec *rr) { int i; const char *s; @@ -554,9 +554,9 @@ static char* process_tags(header_entry *hdr, request_rec *r) for (i = 0; i < hdr->ta->nelts; i++) { s = tag[i].func(r, tag[i].arg); if (str == NULL) - str = apr_pstrdup(r->pool, s); + str = apr_pstrdup(rr->pool, s); else - str = apr_pstrcat(r->pool, str, s, NULL); + str = apr_pstrcat(rr->pool, str, s, NULL); } return str ? str : ""; } @@ -615,6 +615,12 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers, echo_do v; int i; const char *val; + request_rec *rr; + + rr = r; + while (rr->main != NULL) { + rr = rr->main; + } for (i = 0; i < fixup->nelts; ++i) { header_entry *hdr = &((header_entry *) (fixup->elts))[i]; @@ -655,17 +661,17 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers, switch (hdr->action) { case hdr_add: - apr_table_addn(headers, hdr->header, process_tags(hdr, r)); + apr_table_addn(headers, hdr->header, process_tags(hdr, r, rr)); break; case hdr_append: - apr_table_mergen(headers, hdr->header, process_tags(hdr, r)); + apr_table_mergen(headers, hdr->header, process_tags(hdr, r, rr)); break; case hdr_merge: val = apr_table_get(headers, hdr->header); if (val == NULL) { - apr_table_addn(headers, hdr->header, process_tags(hdr, r)); + apr_table_addn(headers, hdr->header, process_tags(hdr, r, rr)); } else { - char *new_val = process_tags(hdr, r); + char *new_val = process_tags(hdr, r, rr); apr_size_t new_val_len = strlen(new_val); int tok_found = 0; @@ -702,9 +708,9 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers, break; case hdr_set: if (!strcasecmp(hdr->header, "Content-Type")) { - ap_set_content_type(r, process_tags(hdr, r)); + ap_set_content_type(r, process_tags(hdr, r, rr)); } - apr_table_setn(headers, hdr->header, process_tags(hdr, r)); + apr_table_setn(headers, hdr->header, process_tags(hdr, r, rr)); break; case hdr_unset: apr_table_unset(headers, hdr->header); @@ -719,7 +725,7 @@ static void do_headers_fixup(request_rec *r, apr_table_t *headers, if (apr_table_get(headers, hdr->header)) { edit_do ed; - ed.p = r->pool; + ed.p = rr->pool; ed.hdr = hdr; ed.t = apr_table_make(r->pool, 5); apr_table_do(edit_header, (void *) &ed, headers, hdr->header,