Skip to content

Commit a404336

Browse files
committed
fix stack overflow in some specific scenario
1 parent 4700584 commit a404336

2 files changed

Lines changed: 38 additions & 13 deletions

File tree

nattlua/types/table.lua

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -909,23 +909,28 @@ function META:IsNumericallyIndexed()
909909
return true
910910
end
911911

912-
function META:CopyLiteralness(from)
912+
function META:CopyLiteralness(from, map)
913913
if from.Type ~= self.Type then return self end
914914

915915
if self:Equal(from) then return self end
916916

917-
local self = self:Copy()
917+
map = map or {}
918+
919+
if map[from] then return map[from] end
920+
921+
local copy = self:Copy()
922+
map[from] = copy
918923

919924
for _, keyval_from in ipairs(from:GetData()) do
920-
local keyval, reason = self:FindKeyValExact(keyval_from.key)
925+
local keyval = copy:FindKeyValExact(keyval_from.key)
921926

922927
if keyval then
923-
keyval.key = keyval.key:CopyLiteralness(keyval_from.key)
924-
keyval.val = keyval.val:CopyLiteralness(keyval_from.val)
928+
keyval.key = keyval.key:CopyLiteralness(keyval_from.key, map)
929+
keyval.val = keyval.val:CopyLiteralness(keyval_from.val, map)
925930
end
926931
end
927932

928-
return self
933+
return copy
929934
end
930935

931936
function META:CopyLiteralness2(from)
@@ -984,6 +989,7 @@ function META:Copy(map--[[#: Map<|any, any|> | nil]], copy_tables)
984989

985990
local copy = META.New()
986991
map[self] = copy -- map any lua references from self to this new copy
992+
987993
for i, keyval in ipairs(self.Data) do
988994
local k = copy_val(keyval.key, map, copy_tables)
989995
local v = copy_val(keyval.val, map, copy_tables)
@@ -995,13 +1001,18 @@ function META:Copy(map--[[#: Map<|any, any|> | nil]], copy_tables)
9951001

9961002
if self.Self then
9971003
local tbl = self.Self
998-
local m, c = tbl.MetaTable, tbl.Contract
999-
tbl.MetaTable = false
1000-
tbl.Contract = false
1001-
local tbl_copy = copy_val(self.Self, map, copy_tables)
1002-
tbl.MetaTable = m
1003-
tbl.Contract = c
1004-
copy:SetSelf(tbl_copy)
1004+
1005+
if map[tbl] then
1006+
copy:SetSelf(map[tbl])
1007+
else
1008+
local m, c = tbl.MetaTable, tbl.Contract
1009+
tbl.MetaTable = false
1010+
tbl.Contract = false
1011+
local tbl_copy = copy_val(self.Self, map, copy_tables)
1012+
tbl.MetaTable = m
1013+
tbl.Contract = c
1014+
copy:SetSelf(tbl_copy)
1015+
end
10051016
end
10061017

10071018
copy.Self2 = self.Self2

test/tests/nattlua/analyzer/table.lua

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,3 +1176,17 @@ for i, v in ipairs(x) do
11761176
end
11771177
attest.equal(x, _ as {foo = 1, bar = 2, faz = 3})
11781178
]]
1179+
1180+
analyze[[
1181+
local META = {}
1182+
META.Type = "table"
1183+
type META.@Self = {}
1184+
type META.@Self.literal_data_cache = META.@Self
1185+
type META.@Name = "TTable"
1186+
function META.Foo(visited: META.@Self)
1187+
visited = visited
1188+
end
1189+
local v = {}
1190+
v.literal_data_cache = v
1191+
META.Foo(v)
1192+
]]

0 commit comments

Comments
 (0)