LuaBlock: run in separate environment, add a "mem" table

This commit is contained in:
upsilon 2020-05-09 13:18:44 +02:00
parent 7ba7a5cceb
commit de765f7f7b
No known key found for this signature in database
GPG Key ID: A80DAE1F266E1C3C

View File

@ -120,25 +120,30 @@ minetest.register_node("moremesecons_luablock:luablock", {
minetest.log("warning", "[moremesecons_luablock] Metadata of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match its mod storage data!") minetest.log("warning", "[moremesecons_luablock] Metadata of LuaBlock at pos "..minetest.pos_to_string(npos).." does not match its mod storage data!")
return return
end end
-- We do absolutely no check there.
-- There is no limitation in the number of instruction the LuaBlock can execute local env = {}
-- or the usage it can make of loops. for k, v in pairs(_G) do
-- It is executed in the global namespace. env[k] = v
-- Remember: *The LuaBlock is highly dangerous and should be manipulated cautiously!* end
local func, err = loadstring(code) env.pos = table.copy(npos)
env.mem = minetest.deserialize(meta:get_string("mem")) or {}
local func, err
if _VERSION == "Lua 5.1" then
func, err = loadstring(code)
if func then
setfenv(func, env)
end
else
func, err = load(code, nil, "t", env)
end
if not func then if not func then
meta:set_string("errmsg", err) meta:set_string("errmsg", err)
make_formspec(meta, pos) make_formspec(meta, pos)
return return
end end
-- Set the "pos" global
local old_pos
if minetest.global_exists("pos") then
old_pos = pos -- In case there's already an existing "pos" global
end
pos = table.copy(npos)
local good, err = pcall(func) local good, err = pcall(func)
pos = old_pos
if not good then -- Runtime error if not good then -- Runtime error
meta:set_string("errmsg", err) meta:set_string("errmsg", err)
@ -146,6 +151,8 @@ minetest.register_node("moremesecons_luablock:luablock", {
return return
end end
meta:set_string("mem", minetest.serialize(env.mem))
meta:set_string("errmsg", "") meta:set_string("errmsg", "")
make_formspec(meta, pos) make_formspec(meta, pos)
end end