forked from minetest-mods/mesecons
Luacontroller: Fix function usage in LuaJIT, make 'do' no longer
prohibited, remove pcall and xpcall, fix global lookup of "jit" variable, correct error locations Thanks to @ShadowNinja and @gamemanj for fixing this in #241
This commit is contained in:
parent
e5dba66c21
commit
08b14e3af0
@ -249,8 +249,8 @@ end
|
||||
|
||||
|
||||
local safe_globals = {
|
||||
"assert", "error", "ipairs", "next", "pairs", "pcall", "select",
|
||||
"tonumber", "tostring", "type", "unpack", "_VERSION", "xpcall",
|
||||
"assert", "error", "ipairs", "next", "pairs", "select",
|
||||
"tonumber", "tostring", "type", "unpack", "_VERSION"
|
||||
}
|
||||
local function create_environment(pos, mem, event)
|
||||
-- Gather variables for the environment
|
||||
@ -340,17 +340,17 @@ end
|
||||
|
||||
local function timeout()
|
||||
debug.sethook() -- Clear hook
|
||||
error("Code timed out!")
|
||||
error("Code timed out!", 2)
|
||||
end
|
||||
|
||||
|
||||
local function code_prohibited(code)
|
||||
-- LuaJIT doesn't increment the instruction counter when running
|
||||
-- loops, so we have to sanitize inputs if we're using LuaJIT.
|
||||
if not jit then
|
||||
if not rawget(_G, "jit") then
|
||||
return false
|
||||
end
|
||||
local prohibited = {"while", "for", "do", "repeat", "until", "goto"}
|
||||
local prohibited = {"while", "for", "repeat", "until", "goto"}
|
||||
code = " "..code.." "
|
||||
for _, p in ipairs(prohibited) do
|
||||
if string.find(code, "[^%w_]"..p.."[^%w_]") then
|
||||
@ -369,10 +369,26 @@ local function create_sandbox(code, env)
|
||||
setfenv(f, env)
|
||||
|
||||
return function(...)
|
||||
debug.sethook(timeout, "", 10000)
|
||||
-- Normal Lua: Use instruction counter to stop execution
|
||||
-- after luacontroller_maxevents.
|
||||
-- LuaJIT: Count function calls instead of instructions, allows usage
|
||||
-- of function keyword. However, LuaJIT still doesn't trigger
|
||||
-- lines events when using infinite loops.
|
||||
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
|
||||
if not rawget(_G, "jit") then
|
||||
debug.sethook(timeout, "", maxevents)
|
||||
else
|
||||
local events = 0
|
||||
debug.sethook(function ()
|
||||
events = events + 1
|
||||
if events > maxevents then
|
||||
timeout()
|
||||
end
|
||||
end, "c")
|
||||
end
|
||||
local ok, ret = pcall(f, ...)
|
||||
debug.sethook() -- Clear hook
|
||||
if not ok then error(ret) end
|
||||
if not ok then error(ret, 0) end
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user