mirror of
https://github.com/minetest-mods/mesecons.git
synced 2025-07-01 23:30:21 +02:00
Fixed bugs around pcall/xpcall and a lexer messup
pcall and xpcall no longer magically disable the infinite loop security(Note: This can actually crash a server, even without the ability to use loops), and the lexer now continues lexing after a unknown character instead of rolling it all into cleanup.
This commit is contained in:
@ -245,9 +245,11 @@ end
|
|||||||
|
|
||||||
|
|
||||||
local safe_globals = {
|
local safe_globals = {
|
||||||
"assert", "error", "ipairs", "next", "pairs", "pcall", "select",
|
"assert", "error", "ipairs", "next", "pairs", "select",
|
||||||
"tonumber", "tostring", "type", "unpack", "_VERSION", "xpcall",
|
"tonumber", "tostring", "type", "unpack", "_VERSION",
|
||||||
}
|
}
|
||||||
|
--This error is used as a signal to pcall, because otherwise someone could deliberately set off a timeout to disable the debug hooks.
|
||||||
|
local timeout_error="Code timed out!"
|
||||||
local function create_environment(pos, mem, event)
|
local function create_environment(pos, mem, event)
|
||||||
-- Gather variables for the environment
|
-- Gather variables for the environment
|
||||||
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
|
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
|
||||||
@ -329,20 +331,41 @@ local function create_environment(pos, mem, event)
|
|||||||
env[name] = _G[name]
|
env[name] = _G[name]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
env.pcall=function(...)
|
||||||
|
local pcr={pcall(...)}
|
||||||
|
if not pcr[1] then
|
||||||
|
if pcr[2]~=timeout_error then
|
||||||
|
error(pcr[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return unpack(pcr)
|
||||||
|
end
|
||||||
|
|
||||||
|
--Only input differs-this wrapper exists to catch certain outputs that shouldn't be caught by a (x)pcall
|
||||||
|
|
||||||
|
env.xpcall=function(...)
|
||||||
|
local pcr={xpcall(...)}
|
||||||
|
if not pcr[1] then
|
||||||
|
if pcr[2]~=timeout_error then
|
||||||
|
error(pcr[2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return unpack(pcr)
|
||||||
|
end
|
||||||
|
|
||||||
return env
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function timeout()
|
local function timeout()
|
||||||
debug.sethook() -- Clear hook
|
debug.sethook() -- Clear hook
|
||||||
error("Code timed out!")
|
error(timeout_error)
|
||||||
end
|
end
|
||||||
|
|
||||||
--A VERY minimalistic lexer, does what it needs to for this job and no more.
|
--A VERY minimalistic lexer, does what it needs to for this job and no more.
|
||||||
--For now, block comments aren't implemented, but are detected.
|
|
||||||
local function lexLua(code)
|
local function lexLua(code)
|
||||||
local lexElements={}
|
local lexElements={}
|
||||||
--Find keywords, whitespace, strings, and then everything else is "unknownchar"
|
--Find keywords, whitespace, strings, and then everything else is "cleanup"
|
||||||
|
|
||||||
--Keywords and numbers.
|
--Keywords and numbers.
|
||||||
function lexElements.keyword(str)
|
function lexElements.keyword(str)
|
||||||
@ -353,7 +376,7 @@ local function lexLua(code)
|
|||||||
end
|
end
|
||||||
--Unimplemented stuff goes here.
|
--Unimplemented stuff goes here.
|
||||||
function lexElements.cleanup(str)
|
function lexElements.cleanup(str)
|
||||||
return str:match("^.+")
|
return str:match("^.")
|
||||||
end
|
end
|
||||||
function lexElements.string(str)
|
function lexElements.string(str)
|
||||||
--Now parse a string.
|
--Now parse a string.
|
||||||
|
Reference in New Issue
Block a user