From 67636964378acff3c1402b2e82d04805b59ba707 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Wed, 16 Jan 2019 15:09:15 -0800 Subject: [PATCH] synchronized with lua-nginx-module #52af63a. feature: ngx.req.get_post_args(), ngx.req.get_uri_args(), ngx.req.get_headers(), ngx.resp.get_headers(), and ngx.decode_args() now would return an error string, "truncated", when the input exceeds the max_args/max_headers limits. bugfix: ngx.resp.get_headers(): the max_headers limit did not cover builtin headers. --- src/http/ngx_http_lua_headers.c | 65 ++++++++++++++++++++-------- src/subsys/ngx_subsys_lua_args.c.tt2 | 16 ++++--- 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/http/ngx_http_lua_headers.c b/src/http/ngx_http_lua_headers.c index 8c4652d..6911bdf 100644 --- a/src/http/ngx_http_lua_headers.c +++ b/src/http/ngx_http_lua_headers.c @@ -397,6 +397,7 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) int max; int raw = 0; int count = 0; + int truncated = 0; n = lua_gettop(L); @@ -425,15 +426,17 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) part = &r->headers_in.headers.part; count = part->nelts; - while (part->next) { + while (part->next != NULL) { part = part->next; count += part->nelts; } if (max > 0 && count > max) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua exceeding request header limit %d > %d", count, + max); count = max; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua exceeding request header limit %d", max); + truncated = 1; } lua_createtable(L, 0, count); @@ -481,9 +484,14 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L) "lua request header: \"%V: %V\"", &header[i].key, &header[i].value); - if (--count == 0) { - return 1; + if (--count <= 0) { + break; } + } /* for */ + + if (truncated) { + lua_pushliteral(L, "truncated"); + return 2; } return 1; @@ -505,6 +513,8 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) int max; int raw = 0; int count = 0; + int truncated = 0; + int extra = 0; n = lua_gettop(L); @@ -549,18 +559,12 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) part = &r->headers_out.headers.part; count = part->nelts; - while (part->next) { + while (part->next != NULL) { part = part->next; count += part->nelts; } - if (max > 0 && count > max) { - count = max; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua exceeding request header limit %d", max); - } - - lua_createtable(L, 0, count); + lua_createtable(L, 0, count + 2); if (!raw) { lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( @@ -571,6 +575,7 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) #if 1 if (r->headers_out.content_type.len) { + extra++; lua_pushliteral(L, "content-type"); lua_pushlstring(L, (char *) r->headers_out.content_type.data, r->headers_out.content_type.len); @@ -580,11 +585,13 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) if (r->headers_out.content_length == NULL && r->headers_out.content_length_n >= 0) { + extra++; lua_pushliteral(L, "content-length"); lua_pushfstring(L, "%d", (int) r->headers_out.content_length_n); lua_rawset(L, -3); } + extra++; lua_pushliteral(L, "connection"); if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) { lua_pushliteral(L, "upgrade"); @@ -598,12 +605,21 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) lua_rawset(L, -3); if (r->chunked) { + extra++; lua_pushliteral(L, "transfer-encoding"); lua_pushliteral(L, "chunked"); lua_rawset(L, -3); } #endif + if (max > 0 && count + extra > max) { + truncated = 1; + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua exceeding response header limit %d > %d", + count + extra, max); + count = max - extra; + } + part = &r->headers_out.headers.part; header = part->elts; @@ -656,9 +672,14 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) "lua response header: \"%V: %V\"", &header[i].key, &header[i].value); - if (--count == 0) { - return 1; + if (--count <= 0) { + break; } + } /* for */ + + if (truncated) { + lua_pushliteral(L, "truncated"); + return 2; } return 1; @@ -1086,7 +1107,8 @@ ngx_http_lua_create_headers_metatable(ngx_log_t *log, lua_State *L) #ifndef NGX_LUA_NO_FFI_API int -ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max) +ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max, + int *truncated) { int count; ngx_list_part_t *part; @@ -1095,21 +1117,26 @@ ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max) return NGX_HTTP_LUA_FFI_BAD_CONTEXT; } + *truncated = 0; + if (max < 0) { max = NGX_HTTP_LUA_MAX_HEADERS; } part = &r->headers_in.headers.part; count = part->nelts; - while (part->next) { + while (part->next != NULL) { part = part->next; count += part->nelts; } if (max > 0 && count > max) { + *truncated = 1; + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua exceeding request header limit %d > %d", count, + max); count = max; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua exceeding request header limit %d", max); } return count; diff --git a/src/subsys/ngx_subsys_lua_args.c.tt2 b/src/subsys/ngx_subsys_lua_args.c.tt2 index d91988e..fe91c15 100644 --- a/src/subsys/ngx_subsys_lua_args.c.tt2 +++ b/src/subsys/ngx_subsys_lua_args.c.tt2 @@ -313,10 +313,12 @@ ngx_[% subsys %]_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max } if (max > 0 && ++count == max) { - ngx_log_debug1(NGX_LOG_DEBUG_[% SUBSYS %], ngx_cycle->log, 0, - "lua hit query args limit %d", max); + lua_pushliteral(L, "truncated"); - return 1; + ngx_log_debug1(NGX_LOG_DEBUG_[% SUBSYS %], ngx_cycle->log, 0, + "[% log_prefix %]lua hit query args limit %d", + max); + return 2; } } else { @@ -390,7 +392,8 @@ ngx_[% subsys %]_lua_ffi_req_get_querystring_len([% req_type %] *r) int -ngx_[% subsys %]_lua_ffi_req_get_uri_args_count([% req_type %] *r, int max) +ngx_[% subsys %]_lua_ffi_req_get_uri_args_count([% req_type %] *r, int max, + int *truncated) { int count; u_char *p, *last; @@ -399,6 +402,8 @@ ngx_[% subsys %]_lua_ffi_req_get_uri_args_count([% req_type %] *r, int max) return NGX_[% SUBSYS %]_LUA_FFI_BAD_CONTEXT; } + *truncated = 0; + if (max < 0) { max = NGX_[% SUBSYS %]_LUA_MAX_ARGS; } @@ -420,8 +425,9 @@ ngx_[% subsys %]_lua_ffi_req_get_uri_args_count([% req_type %] *r, int max) if (count) { if (max > 0 && count > max) { count = max; + *truncated = 1; ngx_log_debug1(NGX_LOG_DEBUG_[% SUBSYS %], r->connection->log, 0, - "lua hit query args limit %d", max); + "[% log_prefix %]lua hit query args limit %d", max); } return count;