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 {
~^/(?<bar>[0-9]).*$ $bar;
}
location ~(?<bar>[0-9]*)[a-z]*$ {
return 200 $1:$foo;
}
location ~(?<bar>[0-9]*)[a-z]*$ {
set $qux $1:$foo;
return 200 $qux;
}
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);
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;
}
return NGX_ERROR;
}
- *value = e.buf;
+ value->data = e.buf.data;
+ value->len = e.pos - e.buf.data;
return NGX_OK;
}
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;
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;
return NULL;
}
+ value->len = e.pos + len - value->data;
+
return e.pos;
}
}
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);
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++;
}
} 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;
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);
return NGX_ERROR;
}
- *value = e.buf;
+ value->data = e.buf.data;
+ value->len = e.pos - e.buf.data;
return NGX_OK;
}
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;
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;
return NULL;
}
+ value->len = e.pos + len - value->data;
+
return e.pos;
}
}
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);