mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-15 02:12:42 -04:00
Fix __gc and use raw metatable when it's disabled
This fixes a small __gc abuse I found, and also uses the raw metatable in a safe way when __gc is disabled. Both were tested.
This commit is contained in:
parent
ac64edd1c7
commit
07f452125c
@ -683,7 +683,7 @@ sandbox = {
|
||||
end
|
||||
local result = getmetatable(t)
|
||||
-- check if we have a wrapped __gc using mt
|
||||
if type(result) == "table" and rawget(result, "__gc") == sgc then
|
||||
if type(result) == "table" and system.allowGC() and rawget(result, "__gc") == sgc then
|
||||
result = rawget(result, "mt")
|
||||
end
|
||||
return result
|
||||
@ -713,7 +713,11 @@ sandbox = {
|
||||
if type(mt) ~= "table" then
|
||||
return setmetatable(t, mt)
|
||||
end
|
||||
if type(rawget(mt, "__gc")) == "function" then
|
||||
if rawget(mt, "__gc") ~= nil then -- If __gc is set to ANYTHING not `nil`, we're gonna have issues
|
||||
-- Garbage collector callbacks apparently can't be sandboxed after
|
||||
-- all, because hooks are disabled while they're running. So we just
|
||||
-- disable them altogether by default.
|
||||
if system.allowGC() then
|
||||
-- For all user __gc functions we enforce a much tighter deadline.
|
||||
-- This is because these functions may be called from the main
|
||||
-- thread under certain circumstanced (such as when saving the world),
|
||||
@ -723,16 +727,18 @@ sandbox = {
|
||||
for k, v in next, mt do
|
||||
sbmt[k] = v
|
||||
end
|
||||
sbmt.mt = mt
|
||||
-- Garbage collector callbacks apparently can't be sandboxed after
|
||||
-- all, because hooks are disabled while they're running. So we just
|
||||
-- disable them altogether by default.
|
||||
if not system.allowGC() then
|
||||
sbmt.__gc = nil -- Silent fail for backwards compat. TODO error in OC 1.7
|
||||
else
|
||||
sbmt.__gc = sgc
|
||||
end
|
||||
sbmt.mt = mt
|
||||
mt = sbmt
|
||||
else
|
||||
-- Don't allow marking for finalization, but use the raw metatable.
|
||||
local gc = rawget(mt, "__gc")
|
||||
rawset(mt, "__gc", nil) -- remove __gc
|
||||
local ret = table.pack(pcall(setmetatable, t, mt))
|
||||
rawset(mt, "__gc", gc) -- restore __gc
|
||||
if not ret[1] then error(ret[2], 0) end
|
||||
return table.unpack(ret, 1, ret.n)
|
||||
end
|
||||
end
|
||||
return setmetatable(t, mt)
|
||||
end,
|
||||
|
Loading…
x
Reference in New Issue
Block a user