Skip to content

Commit

Permalink
Fix __gc and use raw metatable when it's disabled
Browse files Browse the repository at this point in the history
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
  • Loading branch information
SoniEx2 authored and fnuecke committed Jan 31, 2016
1 parent 0f01f6d commit d4addfd
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/main/resources/assets/opencomputers/lua/machine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand All @@ -723,16 +727,18 @@ sandbox = {
for k, v in pairs(mt) do
sbmt[k] = v
end
sbmt.__gc = sgc
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
mt = sbmt
else
sbmt.__gc = sgc
-- 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,
Expand Down Expand Up @@ -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)

0 comments on commit d4addfd

Please sign in to comment.