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.
# Conflicts:
#	src/main/resources/assets/opencomputers/lua/machine.lua
This commit is contained in:
Soni L 2016-01-31 14:46:52 -02:00 committed by Florian Nücke
parent 0f01f6d424
commit d4addfd8e4

View File

@ -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 pairs(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
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
mt = sbmt
end
return setmetatable(t, mt)
end,
@ -1442,4 +1448,4 @@ end
-- JNLua converts the coroutine to a string immediately, so we can't get the
-- traceback later. Because of that we have to do the error handling here.
return pcall(main)
return pcall(main)