Skip to content

Commit

Permalink
bugfix: ngx.say and ngx.print might cause nginx to crash when table-t…
Browse files Browse the repository at this point in the history
…yped arguments were given. thanks sztanpet for reporting this in github issue #54.
  • Loading branch information
agentzh committed Jun 24, 2012
1 parent 0428b88 commit 0178d4e
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 17 deletions.
4 changes: 2 additions & 2 deletions src/ngx_http_lua_bodyfilterby.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
41 changes: 30 additions & 11 deletions src/ngx_http_lua_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions src/ngx_http_lua_output.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
4 changes: 2 additions & 2 deletions src/ngx_http_lua_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
24 changes: 24 additions & 0 deletions t/002-content.t
Original file line number Diff line number Diff line change
Expand Up @@ -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
20 changes: 20 additions & 0 deletions t/082-body-filter.t
Original file line number Diff line number Diff line change
Expand Up @@ -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]

0 comments on commit 0178d4e

Please sign in to comment.