Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

bugfix: ngx.say and ngx.print might cause nginx to crash when table-t…

…yped arguments were given. thanks sztanpet for reporting this in github issue #54.
  • Loading branch information...
commit 0178d4e7b8bac3727aa5fa69b3a65f89de8b6181 1 parent 0428b88
@agentzh agentzh authored
View
4 src/ngx_http_lua_bodyfilterby.c
@@ -543,7 +543,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
return 0;
case LUA_TTABLE:
- size = ngx_http_lua_calc_strlen_in_table(L, 3 /* index */,
+ size = ngx_http_lua_calc_strlen_in_table(L, 3 /* index */, 3 /* arg */,
1 /* strict */);
data = NULL;
break;
@@ -605,7 +605,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
}
if (type == LUA_TTABLE) {
- cl->buf->last = ngx_http_lua_copy_str_in_table(L, cl->buf->last);
+ cl->buf->last = ngx_http_lua_copy_str_in_table(L, 3, cl->buf->last);
} else {
cl->buf->last = ngx_copy(cl->buf->pos, data, size);
View
41 src/ngx_http_lua_output.c
@@ -110,7 +110,8 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline)
case LUA_TTABLE:
- size += ngx_http_lua_calc_strlen_in_table(L, i, 0 /* strict */);
+ size += ngx_http_lua_calc_strlen_in_table(L, i, i,
+ 0 /* strict */);
break;
case LUA_TLIGHTUSERDATA:
@@ -187,7 +188,7 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline)
break;
case LUA_TTABLE:
- b->last = ngx_http_lua_copy_str_in_table(L, b->last);
+ b->last = ngx_http_lua_copy_str_in_table(L, i, b->last);
break;
case LUA_TLIGHTUSERDATA:
@@ -242,7 +243,8 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline)
size_t
-ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i, unsigned strict)
+ngx_http_lua_calc_strlen_in_table(lua_State *L, int index, int arg_i,
+ unsigned strict)
{
double key;
int max;
@@ -252,11 +254,24 @@ ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i, unsigned strict)
size_t len;
const char *msg;
+ if (index < 0) {
+ index = lua_gettop(L) + index + 1;
+ }
+
+ dd("table index: %d", index);
+
max = 0;
lua_pushnil(L); /* stack: table key */
- while (lua_next(L, -2) != 0) { /* stack: table key value */
- if (lua_type(L, -2) == LUA_TNUMBER && (key = lua_tonumber(L, -2))) {
+ while (lua_next(L, index) != 0) { /* stack: table key value */
+ dd("key type: %s", luaL_typename(L, -2));
+
+ if (lua_type(L, -2) == LUA_TNUMBER) {
+
+ key = lua_tonumber(L, -2);
+
+ dd("key value: %d", (int) key);
+
if (floor(key) == key && key >= 1) {
if (key > max) {
max = key;
@@ -278,7 +293,7 @@ ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i, unsigned strict)
size = 0;
for (i = 1; i <= max; i++) {
- lua_rawgeti(L, -1, i); /* stack: table value */
+ lua_rawgeti(L, index, i); /* stack: table value */
type = lua_type(L, -1);
switch (type) {
@@ -315,7 +330,7 @@ ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i, unsigned strict)
case LUA_TTABLE:
- size += ngx_http_lua_calc_strlen_in_table(L, arg_i, strict);
+ size += ngx_http_lua_calc_strlen_in_table(L, -1, arg_i, strict);
break;
case LUA_TLIGHTUSERDATA:
@@ -347,7 +362,7 @@ ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i, unsigned strict)
u_char *
-ngx_http_lua_copy_str_in_table(lua_State *L, u_char *dst)
+ngx_http_lua_copy_str_in_table(lua_State *L, int index, u_char *dst)
{
double key;
int max;
@@ -356,10 +371,14 @@ ngx_http_lua_copy_str_in_table(lua_State *L, u_char *dst)
size_t len;
u_char *p;
+ if (index < 0) {
+ index = lua_gettop(L) + index + 1;
+ }
+
max = 0;
lua_pushnil(L); /* stack: table key */
- while (lua_next(L, -2) != 0) { /* stack: table key value */
+ while (lua_next(L, index) != 0) { /* stack: table key value */
key = lua_tonumber(L, -2);
if (key > max) {
max = key;
@@ -369,7 +388,7 @@ ngx_http_lua_copy_str_in_table(lua_State *L, u_char *dst)
}
for (i = 1; i <= max; i++) {
- lua_rawgeti(L, -1, i); /* stack: table value */
+ lua_rawgeti(L, index, i); /* stack: table value */
type = lua_type(L, -1);
switch (type) {
case LUA_TNUMBER:
@@ -402,7 +421,7 @@ ngx_http_lua_copy_str_in_table(lua_State *L, u_char *dst)
break;
case LUA_TTABLE:
- dst = ngx_http_lua_copy_str_in_table(L, dst);
+ dst = ngx_http_lua_copy_str_in_table(L, -1, dst);
break;
case LUA_TLIGHTUSERDATA:
View
4 src/ngx_http_lua_output.h
@@ -7,10 +7,10 @@
void ngx_http_lua_inject_output_api(lua_State *L);
-size_t ngx_http_lua_calc_strlen_in_table(lua_State *L, int arg_i,
+size_t ngx_http_lua_calc_strlen_in_table(lua_State *L, int index, int arg_i,
unsigned strict);
-u_char * ngx_http_lua_copy_str_in_table(lua_State *L, u_char *dst);
+u_char * ngx_http_lua_copy_str_in_table(lua_State *L, int index, u_char *dst);
#endif /* NGX_HTTP_LUA_OUTPUT_H */
View
4 src/ngx_http_lua_socket.c
@@ -1461,7 +1461,7 @@ ngx_http_lua_socket_tcp_send(lua_State *L)
break;
case LUA_TTABLE:
- len = ngx_http_lua_calc_strlen_in_table(L, 2, 1 /* strict */);
+ len = ngx_http_lua_calc_strlen_in_table(L, 2, 2, 1 /* strict */);
break;
default:
@@ -1493,7 +1493,7 @@ ngx_http_lua_socket_tcp_send(lua_State *L)
break;
case LUA_TTABLE:
- b->last = ngx_http_lua_copy_str_in_table(L, b->last);
+ b->last = ngx_http_lua_copy_str_in_table(L, -1, b->last);
break;
default:
View
24 t/002-content.t
@@ -662,3 +662,27 @@ hello,
world
--- timeout: 5
+
+
+=== TEST 36: ngx.print table arguments (github issue #54)
+--- config
+ location /t {
+ content_by_lua 'ngx.print({10, {0, 5}, 15}, 32)';
+ }
+--- request
+ GET /t
+--- response_body chop
+10051532
+
+
+
+=== TEST 37: ngx.say table arguments (github issue #54)
+--- config
+ location /t {
+ content_by_lua 'ngx.say({10, {0, "5"}, 15}, 32)';
+ }
+--- request
+ GET /t
+--- response_body
+10051532
+
View
20 t/082-body-filter.t
@@ -390,3 +390,23 @@ aaaaaa
--- no_error_log
[error]
+
+
+=== TEST 15: table arguments to ngx.arg[1] (github issue #54)
+--- config
+ location /t {
+ echo -n hello;
+
+ body_filter_by_lua '
+ if ngx.arg[1] ~= "" then
+ ngx.arg[1] = {{ngx.arg[1]}, "!", "\\n"}
+ end
+ ';
+ }
+--- request
+GET /t
+--- response_body
+hello!
+--- no_error_log
+[error]
+
Please sign in to comment.
Something went wrong with that request. Please try again.