From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp51.i.mail.ru (smtp51.i.mail.ru [94.100.177.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 2E28246970E for ; Mon, 10 Feb 2020 10:57:16 +0300 (MSK) From: Olga Arkhangelskaia Date: Mon, 10 Feb 2020 10:57:07 +0300 Message-Id: <20200210075707.86953-1-arkholga@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH] json: fix silent change of global json settings List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: tarantool-patches@dev.tarantool.org When json.decode is used with 2 arguments, 2nd argument seeps out to global json settings. Morover, due to current serialier.cfg implementation it remains invisible while checking settings by json.cfg. To prevent sucj behaviour we stop writing to global serializer struct and use local one, to get one-time action. As was mention before json.cfg can not be trusted in this case, so to check that everything remained unchanged we call decode twice with and without 2nd argument. Closes #4761 --- Issue:https://github.com/tarantool/tarantool/issues/4761 Branch:https://github.com/tarantool/tarantool/tree/OKriw/gh-4761-json.decode-silently-changes-config-when-used-with-config-settings test/app-tap/json.test.lua | 7 ++++++- third_party/lua-cjson/lua_cjson.c | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/test/app-tap/json.test.lua b/test/app-tap/json.test.lua index fadfc74ec..a6b36ff3d 100755 --- a/test/app-tap/json.test.lua +++ b/test/app-tap/json.test.lua @@ -22,7 +22,7 @@ end tap.test("json", function(test) local serializer = require('json') - test:plan(40) + test:plan(41) test:test("unsigned", common.test_unsigned, serializer) test:test("signed", common.test_signed, serializer) @@ -94,6 +94,11 @@ tap.test("json", function(test) 'error: too many nested data structures') test:is(serializer.cfg.decode_max_depth, orig_decode_max_depth, 'global option remains unchanged') + -- + -- gh-4761 json.decode silently changes global settings of json when called + -- with 2d parameter + -- + test:ok(pcall(serializer.decode,'{"1":{"b":{"c":1,"d":null}},"a":1}')) -- -- gh-3514: fix parsing integers with exponent in json diff --git a/third_party/lua-cjson/lua_cjson.c b/third_party/lua-cjson/lua_cjson.c index 3d25814f3..f855cbd80 100644 --- a/third_party/lua-cjson/lua_cjson.c +++ b/third_party/lua-cjson/lua_cjson.c @@ -1004,13 +1004,13 @@ static int json_decode(lua_State *l) luaL_argcheck(l, lua_gettop(l) == 2 || lua_gettop(l) == 1, 1, "expected 1 or 2 arguments"); + struct luaL_serializer *cfg = luaL_checkserializer(l); + struct luaL_serializer user_cfg = *cfg; + json.cfg = cfg; if (lua_gettop(l) == 2) { - struct luaL_serializer *user_cfg = luaL_checkserializer(l); - luaL_serializer_parse_options(l, user_cfg); + luaL_serializer_parse_options(l, &user_cfg); lua_pop(l, 1); - json.cfg = user_cfg; - } else { - json.cfg = luaL_checkserializer(l); + json.cfg = &user_cfg; } json.data = luaL_checklstring(l, 1, &json_len); -- 2.20.1 (Apple Git-117)