From: Roman Arutyunyan Date: Fri, 3 Jul 2026 11:11:09 +0000 (+0400) Subject: Script: avoid garbage at the end of the result string X-Git-Tag: release-1.31.3~3 X-Git-Url: http://git.kaiwu.me/http/$%7BGITURL%7D/doc/static/gitweb.js?a=commitdiff_plain;h=a8289aa69c74f7e664ad63b91c17aa2a554f190f;p=nginx.git Script: avoid garbage at the end of the result string If the script result turned out to be shorter than its predicted length, the result string contained uninitialized bytes at the end. The fix is to cut the result string by its actual size. The following locations returned trailing garbage to the client with URI "/1234abcd". map $uri $foo { ~^/(?[0-9]).*$ $bar; } location ~(?[0-9]*)[a-z]*$ { return 200 $1:$foo; } location ~(?[0-9]*)[a-z]*$ { set $qux $1:$foo; return 200 $qux; } --- diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c index ff3b68716..eefe4c8c8 100644 --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -966,10 +966,11 @@ static char * ngx_http_rewrite_value(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, ngx_str_t *value) { - ngx_int_t n; - ngx_http_script_compile_t sc; - ngx_http_script_value_code_t *val; - ngx_http_script_complex_value_code_t *complex; + ngx_int_t n; + ngx_http_script_compile_t sc; + ngx_http_script_value_code_t *val; + ngx_http_script_complex_value_code_t *complex; + ngx_http_script_complex_value_end_code_t *complex_end; n = ngx_http_script_variables_count(value); @@ -1016,5 +1017,14 @@ ngx_http_rewrite_value(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf, return NGX_CONF_ERROR; } + complex_end = ngx_http_script_add_code(lcf->codes, + sizeof(ngx_http_script_complex_value_end_code_t), + &complex); + if (complex_end == NULL) { + return NGX_CONF_ERROR; + } + + complex_end->code = ngx_http_script_complex_value_end_code; + return NGX_CONF_OK; } diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c index c7e28b231..4d0a67084 100644 --- a/src/http/ngx_http_script.c +++ b/src/http/ngx_http_script.c @@ -103,7 +103,8 @@ ngx_http_complex_value(ngx_http_request_t *r, ngx_http_complex_value_t *val, return NGX_ERROR; } - *value = e.buf; + value->data = e.buf.data; + value->len = e.pos - e.buf.data; return NGX_OK; } @@ -622,6 +623,7 @@ u_char * ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, void *code_lengths, size_t len, void *code_values) { + size_t n; ngx_uint_t i; ngx_http_script_code_pt code; ngx_http_script_len_code_pt lcode; @@ -643,21 +645,23 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, e.request = r; e.flushed = 1; + n = len; + while (*(uintptr_t *) e.ip) { lcode = *(ngx_http_script_len_code_pt *) e.ip; - len += lcode(&e); + n += lcode(&e); } - value->len = len; - value->data = ngx_pnalloc(r->pool, len); + value->len = n; + value->data = ngx_pnalloc(r->pool, n); if (value->data == NULL) { return NULL; } e.ip = code_values; e.pos = value->data; - e.end = value->data + len; + e.end = value->data + n; while (*(uintptr_t *) e.ip) { code = *(ngx_http_script_code_pt *) e.ip; @@ -668,6 +672,8 @@ ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value, return NULL; } + value->len = e.pos + len - value->data; + return e.pos; } @@ -1551,6 +1557,8 @@ ngx_http_script_full_name_code(ngx_http_script_engine_t *e) } e->buf = value; + e->pos = value.data + value.len; + e->end = e->pos; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, "http script fullname: \"%V\"", &value); @@ -1859,8 +1867,18 @@ ngx_http_script_complex_value_code(ngx_http_script_engine_t *e) e->pos = e->buf.data; e->end = e->buf.data + len; +} + + +void +ngx_http_script_complex_value_end_code(ngx_http_script_engine_t *e) +{ + e->ip += sizeof(ngx_http_script_complex_value_end_code_t); + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0, + "http script complex value end"); - e->sp->len = e->buf.len; + e->sp->len = e->pos - e->buf.data; e->sp->data = e->buf.data; e->sp++; } diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h index b086b266f..4f2fbd16e 100644 --- a/src/http/ngx_http_script.h +++ b/src/http/ngx_http_script.h @@ -200,6 +200,11 @@ typedef struct { } ngx_http_script_complex_value_code_t; +typedef struct { + ngx_http_script_code_pt code; +} ngx_http_script_complex_value_end_code_t; + + typedef struct { ngx_http_script_code_pt code; uintptr_t value; @@ -263,6 +268,7 @@ void ngx_http_script_equal_code(ngx_http_script_engine_t *e); void ngx_http_script_not_equal_code(ngx_http_script_engine_t *e); void ngx_http_script_file_code(ngx_http_script_engine_t *e); void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e); +void ngx_http_script_complex_value_end_code(ngx_http_script_engine_t *e); void ngx_http_script_value_code(ngx_http_script_engine_t *e); void ngx_http_script_set_var_code(ngx_http_script_engine_t *e); void ngx_http_script_var_set_handler_code(ngx_http_script_engine_t *e); diff --git a/src/stream/ngx_stream_script.c b/src/stream/ngx_stream_script.c index 431364b49..54e5dd559 100644 --- a/src/stream/ngx_stream_script.c +++ b/src/stream/ngx_stream_script.c @@ -104,7 +104,8 @@ ngx_stream_complex_value(ngx_stream_session_t *s, return NGX_ERROR; } - *value = e.buf; + value->data = e.buf.data; + value->len = e.pos - e.buf.data; return NGX_OK; } @@ -498,6 +499,7 @@ u_char * ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value, void *code_lengths, size_t len, void *code_values) { + size_t n; ngx_uint_t i; ngx_stream_script_code_pt code; ngx_stream_script_engine_t e; @@ -519,21 +521,23 @@ ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value, e.session = s; e.flushed = 1; + n = len; + while (*(uintptr_t *) e.ip) { lcode = *(ngx_stream_script_len_code_pt *) e.ip; - len += lcode(&e); + n += lcode(&e); } - value->len = len; - value->data = ngx_pnalloc(s->connection->pool, len); + value->len = n; + value->data = ngx_pnalloc(s->connection->pool, n); if (value->data == NULL) { return NULL; } e.ip = code_values; e.pos = value->data; - e.end = value->data + len; + e.end = value->data + n; while (*(uintptr_t *) e.ip) { code = *(ngx_stream_script_code_pt *) e.ip; @@ -544,6 +548,8 @@ ngx_stream_script_run(ngx_stream_session_t *s, ngx_str_t *value, return NULL; } + value->len = e.pos + len - value->data; + return e.pos; } @@ -1064,6 +1070,8 @@ ngx_stream_script_full_name_code(ngx_stream_script_engine_t *e) } e->buf = value; + e->pos = value.data + value.len; + e->end = e->pos; ngx_log_debug1(NGX_LOG_DEBUG_STREAM, e->session->connection->log, 0, "stream script fullname: \"%V\"", &value);