diff options
author | Mark Pulford <mark@kyne.com.au> | 2012-01-17 23:28:10 +1030 |
---|---|---|
committer | Mark Pulford <mark@kyne.com.au> | 2012-03-04 18:54:35 +1030 |
commit | 8faf8490e518315a8eff17a76b019debe48104b4 (patch) | |
tree | 3ab249cd8b9ce70ada61425d2749e0c3b3196f60 /lua_cjson.c | |
parent | e3b3da50f10096de12bb6b47156dd2c94c373a19 (diff) | |
download | lua-cjson-8faf8490e518315a8eff17a76b019debe48104b4.tar.gz lua-cjson-8faf8490e518315a8eff17a76b019debe48104b4.tar.bz2 lua-cjson-8faf8490e518315a8eff17a76b019debe48104b4.zip |
Fix Lua C function stack overflow during encoding
Ensure there are enough Lua stack slots available before descending into
another table during encoding. This fixes a segfault when encoding
deeply nested tables.
This bug wasn't noticed earlier due to the previous limit of 20 nested
tables.
Diffstat (limited to 'lua_cjson.c')
-rw-r--r-- | lua_cjson.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index 00fa2dd..4a2ce0f 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -564,12 +564,17 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json) | |||
564 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, | 564 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, |
565 | int current_depth, strbuf_t *json) | 565 | int current_depth, strbuf_t *json) |
566 | { | 566 | { |
567 | if (current_depth > cfg->encode_max_depth) { | 567 | /* Ensure there are enough slots free to traverse a table (key, value). |
568 | if (!cfg->encode_keep_buffer) | 568 | * luaL_error() and other Lua API functions use space from the |
569 | strbuf_free(json); | 569 | * "EXTRA_STACK" reserve. */ |
570 | luaL_error(l, "Cannot serialise, excessive nesting (%d)", | 570 | if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 2)) |
571 | current_depth); | 571 | return; |
572 | } | 572 | |
573 | if (!cfg->encode_keep_buffer) | ||
574 | strbuf_free(json); | ||
575 | |||
576 | luaL_error(l, "Cannot serialise, excessive nesting (%d)", | ||
577 | current_depth); | ||
573 | } | 578 | } |
574 | 579 | ||
575 | static void json_append_data(lua_State *l, json_config_t *cfg, | 580 | static void json_append_data(lua_State *l, json_config_t *cfg, |
@@ -692,9 +697,9 @@ static void json_append_data(lua_State *l, json_config_t *cfg, | |||
692 | strbuf_append_mem(json, "false", 5); | 697 | strbuf_append_mem(json, "false", 5); |
693 | break; | 698 | break; |
694 | case LUA_TTABLE: | 699 | case LUA_TTABLE: |
695 | len = lua_array_length(l, cfg, json); | ||
696 | current_depth++; | 700 | current_depth++; |
697 | json_check_encode_depth(l, cfg, current_depth, json); | 701 | json_check_encode_depth(l, cfg, current_depth, json); |
702 | len = lua_array_length(l, cfg, json); | ||
698 | if (len > 0) | 703 | if (len > 0) |
699 | json_append_array(l, cfg, current_depth, json, len); | 704 | json_append_array(l, cfg, current_depth, json, len); |
700 | else | 705 | else |