From 9067bdbe2b93515bb0c75ec4be9232c87bc19bea Mon Sep 17 00:00:00 2001 From: "Paul J. Reder" Date: Thu, 23 Aug 2001 15:45:49 +0000 Subject: [PATCH] Fix for mod_include. Ryan's patch to check error codes put a return in the wrong place. Also, the include handler return code wasn't being checked. I don't like macros with returns, so I converted SPLIT_AND_PASS_PRETAG_BUCKETS into a function. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90554 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 7 +++++++ modules/filters/mod_include.c | 39 +++++++++++++++++++++++++++++++---- modules/filters/mod_include.h | 16 -------------- modules/generators/mod_cgi.c | 35 +++++++++++++++++++++++++++++-- modules/generators/mod_cgid.c | 35 +++++++++++++++++++++++++++++-- 5 files changed, 108 insertions(+), 24 deletions(-) diff --git a/CHANGES b/CHANGES index db694cd7a3..9553287112 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,11 @@ Changes with Apache 2.0.25-dev + *) Fix for mod_include. Ryan's patch to check error + codes put a return in the wrong place. Also, the + include handler return code wasn't being checked. + I don't like macros with returns, so I converted + SPLIT_AND_PASS_PRETAG_BUCKETS into a function. + [Paul J. Reder ] + *) fix segv in mod_mime if no AddTypes are configured [John Sterling ] diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index 220a747bff..7a902c9bcd 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -98,6 +98,29 @@ static APR_OPTIONAL_FN_TYPE(ap_register_include_handler) *ssi_pfn_register; #define BYTE_COUNT_THRESHOLD AP_MIN_BYTES_TO_WRITE +/* This function is used to split the brigade at the beginning of + * the tag and forward the pretag buckets before any substitution + * work is performed on the tag. This maintains proper ordering. + */ +static int split_and_pass_pretag_buckets(apr_bucket_brigade **brgd, + include_ctx_t *cntxt, + ap_filter_t *next) +{ + apr_bucket_brigade *tag_plus; + int rv; + + if ((APR_BRIGADE_EMPTY(cntxt->ssi_tag_brigade)) && + (cntxt->head_start_bucket != NULL)) { + tag_plus = apr_brigade_split(*brgd, cntxt->head_start_bucket); + rv = ap_pass_brigade(next, *brgd); + cntxt->bytes_parsed = 0; + *brgd = tag_plus; + if (rv != APR_SUCCESS) { + return rv; + } + } +} + /* ------------------------ Environment function -------------------------- */ /* XXX: could use ap_table_overlap here */ @@ -857,7 +880,10 @@ static int handle_include(include_ctx_t *ctx, apr_bucket_brigade **bb, request_r if (!error_fmt) { int rv; - SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next); + rv = split_and_pass_pretag_buckets(bb, ctx, f->next); + if (rv != APR_SUCCESS) { + return rv; + } if ((rv = ap_run_sub_req(rr))) { if (APR_STATUS_IS_EPIPE(rv)) { @@ -2341,7 +2367,6 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb, apr_bucket *dptr = APR_BRIGADE_FIRST(*bb); apr_bucket *tmp_dptr; apr_bucket_brigade *tag_and_after; - int ret; apr_status_t rv; if (r->args) { /* add QUERY stuff to env cause it ain't yet */ @@ -2435,7 +2460,10 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb, *bb = tag_and_after; } else if (ctx->bytes_parsed >= BYTE_COUNT_THRESHOLD) { - SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next); + rv = split_and_pass_pretag_buckets(bb, ctx, f->next); + if (rv != APR_SUCCESS) { + return rv; + } } } else { @@ -2506,7 +2534,10 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb, ctx->combined_tag, ctx->directive_length+1); if (handle_func != NULL) { - ret = (*handle_func)(ctx, bb, r, f, dptr, &content_head); + rv = (*handle_func)(ctx, bb, r, f, dptr, &content_head); + if ((rv != 0) && (rv != 1)) { + return (rv); + } } else { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, diff --git a/modules/filters/mod_include.h b/modules/filters/mod_include.h index 15a3b7b61e..ce7ee58398 100644 --- a/modules/filters/mod_include.h +++ b/modules/filters/mod_include.h @@ -183,22 +183,6 @@ typedef struct include_filter_ctx { } \ } -#define SPLIT_AND_PASS_PRETAG_BUCKETS(brgd, cntxt, next) \ -if ((APR_BRIGADE_EMPTY(cntxt->ssi_tag_brigade)) && \ - (cntxt->head_start_bucket != NULL)) { \ - apr_bucket_brigade *tag_plus; \ - int rv; \ - \ - tag_plus = apr_brigade_split(brgd, cntxt->head_start_bucket); \ - rv = ap_pass_brigade(next, brgd); \ - if (rv != APR_SUCCESS) { \ - return rv; \ - } \ - cntxt->bytes_parsed = 0; \ - brgd = tag_plus; \ -} - - typedef int (include_handler_fn_t)(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec *r, ap_filter_t *f, apr_bucket *head_ptr, apr_bucket **inserted_head); diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c index d54da1d95b..85576e01f7 100644 --- a/modules/generators/mod_cgi.c +++ b/modules/generators/mod_cgi.c @@ -137,6 +137,29 @@ typedef struct { int bufbytes; } cgi_server_conf; +/* This function is used to split the brigade at the beginning of + * the tag and forward the pretag buckets before any substitution + * work is performed on the tag. This maintains proper ordering. + */ +static int split_and_pass_pretag_buckets(apr_bucket_brigade **brgd, + include_ctx_t *cntxt, + ap_filter_t *next) +{ + apr_bucket_brigade *tag_plus; + int rv; + + if ((APR_BRIGADE_EMPTY(cntxt->ssi_tag_brigade)) && + (cntxt->head_start_bucket != NULL)) { + tag_plus = apr_brigade_split(*brgd, cntxt->head_start_bucket); + rv = ap_pass_brigade(next, *brgd); + cntxt->bytes_parsed = 0; + *brgd = tag_plus; + if (rv != APR_SUCCESS) { + return rv; + } + } +} + static void *create_cgi_config(apr_pool_t *p, server_rec *s) { cgi_server_conf *c = @@ -440,7 +463,10 @@ static apr_status_t run_cgi_child(apr_file_t **script_out, else { procnew = apr_pcalloc(p, sizeof(*procnew)); if (e_info->prog_type == RUN_AS_SSI) { - SPLIT_AND_PASS_PRETAG_BUCKETS(*(e_info->bb), e_info->ctx, e_info->next); + rc = split_and_pass_pretag_buckets(e_info->bb, e_info->ctx, e_info->next); + if (rc != APR_SUCCESS) { + return rc; + } } rc = ap_os_create_privileged_process(r, procnew, command, argv, env, procattr, p); @@ -896,6 +922,7 @@ static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec char *tag = NULL; char *tag_val = NULL; char *file = r->filename; + int retval; apr_bucket *tmp_buck; char parsed_string[MAX_STRING_LEN]; @@ -928,7 +955,11 @@ static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec } else if (!strcmp(tag, "cgi")) { cgi_pfn_ps(r, tag_val, parsed_string, sizeof(parsed_string), 0); - SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next); + retval = split_and_pass_pretag_buckets(bb, ctx, f->next); + if (retval != APR_SUCCESS) { + return retval; + } + if (include_cgi(parsed_string, r, f->next, head_ptr, inserted_head) == -1) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, "invalid CGI ref \"%s\" in %s", tag_val, file); diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 900a8f4ca5..e989d11557 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -169,6 +169,29 @@ typedef struct { int bufbytes; } cgid_server_conf; +/* This function is used to split the brigade at the beginning of + * the tag and forward the pretag buckets before any substitution + * work is performed on the tag. This maintains proper ordering. + */ +static int split_and_pass_pretag_buckets(apr_bucket_brigade **brgd, + include_ctx_t *cntxt, + ap_filter_t *next) +{ + apr_bucket_brigade *tag_plus; + int rv; + + if ((APR_BRIGADE_EMPTY(cntxt->ssi_tag_brigade)) && + (cntxt->head_start_bucket != NULL)) { + tag_plus = apr_brigade_split(*brgd, cntxt->head_start_bucket); + rv = ap_pass_brigade(next, *brgd); + cntxt->bytes_parsed = 0; + *brgd = tag_plus; + if (rv != APR_SUCCESS) { + return rv; + } + } +} + /* If a request includes query info in the URL (stuff after "?"), and * the query info does not contain "=" (indicative of a FORM submission), * then this routine is called to create the argument list to be passed @@ -1174,7 +1197,10 @@ static int include_cmd(include_ctx_t *ctx, apr_bucket_brigade **bb, char *comman "unable to connect to cgi daemon"); } - SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next); + retval = split_and_pass_pretag_buckets(bb, ctx, f->next); + if (retval != APR_SUCCESS) { + return retval; + } send_req(sd, r, command, env, SSI_REQ); @@ -1235,6 +1261,7 @@ static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec char *file = r->filename; apr_bucket *tmp_buck; char parsed_string[MAX_STRING_LEN]; + int retval; *inserted_head = NULL; if (ctx->flags & FLAG_PRINTING) { @@ -1266,7 +1293,11 @@ static int handle_exec(include_ctx_t *ctx, apr_bucket_brigade **bb, request_rec } else if (!strcmp(tag, "cgi")) { cgid_pfn_ps(r, tag_val, parsed_string, sizeof(parsed_string), 0); - SPLIT_AND_PASS_PRETAG_BUCKETS(*bb, ctx, f->next); + retval = split_and_pass_pretag_buckets(bb, ctx, f->next); + if (retval != APR_SUCCESS) { + return retval; + } + if (include_cgi(parsed_string, r, f->next, head_ptr, inserted_head) == -1) { ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r, "invalid CGI ref \"%s\" in %s", tag_val, file); -- 2.50.1