mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
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
This commit is contained in:
7
CHANGES
7
CHANGES
@@ -1,4 +1,11 @@
|
|||||||
Changes with Apache 2.0.25-dev
|
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 <rederpj@raleigh.ibm.com>]
|
||||||
|
|
||||||
*) fix segv in mod_mime if no AddTypes are configured
|
*) fix segv in mod_mime if no AddTypes are configured
|
||||||
[John Sterling <sterling@covalent.net>]
|
[John Sterling <sterling@covalent.net>]
|
||||||
|
|
||||||
|
@@ -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
|
#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 -------------------------- */
|
/* ------------------------ Environment function -------------------------- */
|
||||||
|
|
||||||
/* XXX: could use ap_table_overlap here */
|
/* 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) {
|
if (!error_fmt) {
|
||||||
int rv;
|
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 ((rv = ap_run_sub_req(rr))) {
|
||||||
if (APR_STATUS_IS_EPIPE(rv)) {
|
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 *dptr = APR_BRIGADE_FIRST(*bb);
|
||||||
apr_bucket *tmp_dptr;
|
apr_bucket *tmp_dptr;
|
||||||
apr_bucket_brigade *tag_and_after;
|
apr_bucket_brigade *tag_and_after;
|
||||||
int ret;
|
|
||||||
apr_status_t rv;
|
apr_status_t rv;
|
||||||
|
|
||||||
if (r->args) { /* add QUERY stuff to env cause it ain't yet */
|
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;
|
*bb = tag_and_after;
|
||||||
}
|
}
|
||||||
else if (ctx->bytes_parsed >= BYTE_COUNT_THRESHOLD) {
|
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 {
|
else {
|
||||||
@@ -2506,7 +2534,10 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb,
|
|||||||
ctx->combined_tag,
|
ctx->combined_tag,
|
||||||
ctx->directive_length+1);
|
ctx->directive_length+1);
|
||||||
if (handle_func != NULL) {
|
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 {
|
else {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
||||||
|
@@ -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,
|
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,
|
request_rec *r, ap_filter_t *f, apr_bucket *head_ptr,
|
||||||
apr_bucket **inserted_head);
|
apr_bucket **inserted_head);
|
||||||
|
@@ -137,6 +137,29 @@ typedef struct {
|
|||||||
int bufbytes;
|
int bufbytes;
|
||||||
} cgi_server_conf;
|
} 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)
|
static void *create_cgi_config(apr_pool_t *p, server_rec *s)
|
||||||
{
|
{
|
||||||
cgi_server_conf *c =
|
cgi_server_conf *c =
|
||||||
@@ -440,7 +463,10 @@ static apr_status_t run_cgi_child(apr_file_t **script_out,
|
|||||||
else {
|
else {
|
||||||
procnew = apr_pcalloc(p, sizeof(*procnew));
|
procnew = apr_pcalloc(p, sizeof(*procnew));
|
||||||
if (e_info->prog_type == RUN_AS_SSI) {
|
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);
|
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 = NULL;
|
||||||
char *tag_val = NULL;
|
char *tag_val = NULL;
|
||||||
char *file = r->filename;
|
char *file = r->filename;
|
||||||
|
int retval;
|
||||||
apr_bucket *tmp_buck;
|
apr_bucket *tmp_buck;
|
||||||
char parsed_string[MAX_STRING_LEN];
|
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")) {
|
else if (!strcmp(tag, "cgi")) {
|
||||||
cgi_pfn_ps(r, tag_val, parsed_string, sizeof(parsed_string), 0);
|
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) {
|
if (include_cgi(parsed_string, r, f->next, head_ptr, inserted_head) == -1) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
||||||
"invalid CGI ref \"%s\" in %s", tag_val, file);
|
"invalid CGI ref \"%s\" in %s", tag_val, file);
|
||||||
|
@@ -169,6 +169,29 @@ typedef struct {
|
|||||||
int bufbytes;
|
int bufbytes;
|
||||||
} cgid_server_conf;
|
} 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
|
/* If a request includes query info in the URL (stuff after "?"), and
|
||||||
* the query info does not contain "=" (indicative of a FORM submission),
|
* the query info does not contain "=" (indicative of a FORM submission),
|
||||||
* then this routine is called to create the argument list to be passed
|
* 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");
|
"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);
|
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;
|
char *file = r->filename;
|
||||||
apr_bucket *tmp_buck;
|
apr_bucket *tmp_buck;
|
||||||
char parsed_string[MAX_STRING_LEN];
|
char parsed_string[MAX_STRING_LEN];
|
||||||
|
int retval;
|
||||||
|
|
||||||
*inserted_head = NULL;
|
*inserted_head = NULL;
|
||||||
if (ctx->flags & FLAG_PRINTING) {
|
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")) {
|
else if (!strcmp(tag, "cgi")) {
|
||||||
cgid_pfn_ps(r, tag_val, parsed_string, sizeof(parsed_string), 0);
|
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) {
|
if (include_cgi(parsed_string, r, f->next, head_ptr, inserted_head) == -1) {
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
|
||||||
"invalid CGI ref \"%s\" in %s", tag_val, file);
|
"invalid CGI ref \"%s\" in %s", tag_val, file);
|
||||||
|
Reference in New Issue
Block a user