summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCiel Zhao <i@ciel.dev>2022-11-21 17:01:34 +0300
committerCiel Zhao <i@ciel.dev>2022-11-21 17:01:34 +0300
commit053e40e5d45ac76ea29b803840222461f501f1e3 (patch)
tree4fc9a2acf46d033943d1fabf4b911a76abbfd4b4
parent67e2a6916170f126a078bf7499a9a02c994e2f6d (diff)
downloadnginx-053e40e5d45ac76ea29b803840222461f501f1e3.tar.gz
SSI: handling of subrequests from other modules (ticket #1263).
As the SSI parser always uses the context from the main request for storing variables and blocks, that context should always exist for subrequests using SSI, even though the main request does not necessarily have SSI enabled. However, `ngx_http_get_module_ctx(r->main, ...)` is getting NULL in such cases, resulting in the worker crashing SIGSEGV when accessing its attributes. This patch links the first initialized context to the main request, and upgrades it only when main context is initialized.
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c29
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.h1
2 files changed, 29 insertions, 1 deletions
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 6737965d1..e7601b83e 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -329,7 +329,7 @@ static ngx_http_variable_t ngx_http_ssi_vars[] = {
static ngx_int_t
ngx_http_ssi_header_filter(ngx_http_request_t *r)
{
- ngx_http_ssi_ctx_t *ctx;
+ ngx_http_ssi_ctx_t *ctx, *mctx;
ngx_http_ssi_loc_conf_t *slcf;
slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
@@ -341,6 +341,8 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
return ngx_http_next_header_filter(r);
}
+ mctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -367,6 +369,26 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
r->filter_need_in_memory = 1;
if (r == r->main) {
+
+ if (mctx) {
+
+ /*
+ * if there was a shared context previously used as main,
+ * copy variables and blocks
+ */
+
+ ctx->variables = mctx->variables;
+ ctx->blocks = mctx->blocks;
+
+#if (NGX_PCRE)
+ ctx->ncaptures = mctx->ncaptures;
+ ctx->captures = mctx->captures;
+ ctx->captures_data = mctx->captures_data;
+#endif
+
+ mctx->shared = 0;
+ }
+
ngx_http_clear_content_length(r);
ngx_http_clear_accept_ranges(r);
@@ -379,6 +401,10 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
} else {
ngx_http_weak_etag(r);
}
+
+ } else if (mctx == NULL) {
+ ngx_http_set_ctx(r->main, ctx, ngx_http_ssi_filter_module);
+ ctx->shared = 1;
}
return ngx_http_next_header_filter(r);
@@ -405,6 +431,7 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
if (ctx == NULL
+ || (ctx->shared && r == r->main)
|| (in == NULL
&& ctx->buf == NULL
&& ctx->in == NULL
diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h
index 0bd01a067..419bf977d 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.h
+++ b/src/http/modules/ngx_http_ssi_filter_module.h
@@ -71,6 +71,7 @@ typedef struct {
u_char *captures_data;
#endif
+ unsigned shared:1;
unsigned conditional:2;
unsigned encoding:2;
unsigned block:1;