diff options
author | Mark Pulford <mark@kyne.com.au> | 2012-01-19 20:13:25 +1030 |
---|---|---|
committer | Mark Pulford <mark@kyne.com.au> | 2012-03-04 18:54:35 +1030 |
commit | f62a3d368525b7b2d8f38b68178e1d277b247edf (patch) | |
tree | 5c879f9d6ddf97cc72d4684749f8faff24b61621 | |
parent | 94e85ca17cc72550684e5c9543f8ffca86672de3 (diff) | |
download | lua-cjson-f62a3d368525b7b2d8f38b68178e1d277b247edf.tar.gz lua-cjson-f62a3d368525b7b2d8f38b68178e1d277b247edf.tar.bz2 lua-cjson-f62a3d368525b7b2d8f38b68178e1d277b247edf.zip |
Reserve stack slot for luaL_error() during encode
Unlike "decode", encoding leaves both the key/value on the stack before
descending. This leaves no spare room for luaL_error() in case the depth
check or lua_checkstack() fails. Allocate an extra stack slot to ensure there is always room for
luaL_error() in json_check_encode_depth().
Note: this would not have caused a crash or fault due to the EXTRA_STACK
slot reserve, but it was a misuse of the Lua C API.
-rw-r--r-- | lua_cjson.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/lua_cjson.c b/lua_cjson.c index fea3ed5..f5af350 100644 --- a/lua_cjson.c +++ b/lua_cjson.c | |||
@@ -532,10 +532,17 @@ static int lua_array_length(lua_State *l, json_config_t *cfg, strbuf_t *json) | |||
532 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, | 532 | static void json_check_encode_depth(lua_State *l, json_config_t *cfg, |
533 | int current_depth, strbuf_t *json) | 533 | int current_depth, strbuf_t *json) |
534 | { | 534 | { |
535 | /* Ensure there are enough slots free to traverse a table (key, value). | 535 | /* Ensure there are enough slots free to traverse a table (key, |
536 | * luaL_error() and other Lua API functions use space from the | 536 | * value) and push a string for a potential error message. |
537 | * "EXTRA_STACK" reserve. */ | 537 | * |
538 | if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 2)) | 538 | * Unlike "decode", the key and value are still on the stack when |
539 | * lua_checkstack() is called. Hence an extra slot for luaL_error() | ||
540 | * below is required just in case the next check to lua_checkstack() | ||
541 | * fails. | ||
542 | * | ||
543 | * While this won't cause a crash due to the EXTRA_STACK reserve | ||
544 | * slots, it would still be an improper use of the API. */ | ||
545 | if (current_depth <= cfg->encode_max_depth && lua_checkstack(l, 3)) | ||
539 | return; | 546 | return; |
540 | 547 | ||
541 | if (!cfg->encode_keep_buffer) | 548 | if (!cfg->encode_keep_buffer) |