From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 134E22519C for ; Thu, 11 Jul 2019 07:05:40 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id FFmPxi5qMYWQ for ; Thu, 11 Jul 2019 07:05:40 -0400 (EDT) Received: from smtp56.i.mail.ru (smtp56.i.mail.ru [217.69.128.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id 705272457A for ; Thu, 11 Jul 2019 07:05:39 -0400 (EDT) From: Oleg Babin Subject: [tarantool-patches] [PATCH] table: fix incorrect __metatable handling Date: Thu, 11 Jul 2019 14:05:32 +0300 Message-Id: <20190711110532.10543-1-olegrok@tarantool.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-Help: List-Unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-Subscribe: List-Owner: List-post: List-Archive: To: tarantool-patches@freelists.org Cc: Oleg Babin From: Oleg Babin Closes #4340 Before this patch we get metatabe of original table using "getmetatable" function. It leads to the error if original table contained __metatable. To fix this problem getmetatable was replaced to debug.getmetatable --- src/lua/table.lua | 2 +- test/app-tap/table.test.lua | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/lua/table.lua b/src/lua/table.lua index 7e8ba7aae..d83217dcb 100644 --- a/src/lua/table.lua +++ b/src/lua/table.lua @@ -2,7 +2,7 @@ local function table_deepcopy_internal(orig, cyclic) cyclic = cyclic or {} local copy = orig if type(orig) == 'table' then - local mt, copy_function = getmetatable(orig), nil + local mt, copy_function = debug.getmetatable(orig), nil if mt then copy_function = mt.__copy end if copy_function == nil then copy = {} diff --git a/test/app-tap/table.test.lua b/test/app-tap/table.test.lua index 60c095fdf..07894f69e 100755 --- a/test/app-tap/table.test.lua +++ b/test/app-tap/table.test.lua @@ -8,7 +8,7 @@ yaml.cfg{ encode_invalid_as_nil = true, } local test = require('tap').test('table') -test:plan(31) +test:plan(33) do -- check basic table.copy (deepcopy) local example_table = { @@ -223,4 +223,22 @@ do -- check usage of not __copy metamethod on second level + shallow ) end +do -- gh-4340: deepcopy doesn't handle __metatable correctly. + local original = { + content = 'string' + } + setmetatable(original, { __metatable = 'protection' }) + local copy = table.deepcopy(original) + test:is( + copy.content, + original.content, + "checking that original string was copied" + ) + test:is( + getmetatable(copy), + 'protection', + "checking that __metatable was correctly copied" + ) +end + os.exit(test:check() == true and 0 or 1) -- 2.21.0