Add support for function serialization to minetest.serialize

This commit is contained in:
ShadowNinja 2014-04-23 17:21:17 -04:00
parent f2b93b7bae
commit 0d6e4ef5f3

@ -112,6 +112,8 @@ function minetest.serialize(x)
elseif t=="number" then return tostring(x) elseif t=="number" then return tostring(x)
elseif t=="string" then return string.format("%q", x) elseif t=="string" then return string.format("%q", x)
elseif t=="boolean" then return x and "true" or "false" elseif t=="boolean" then return x and "true" or "false"
elseif t=="function" then
return "loadstring("..string.format("%q", string.dump(x))..")"
elseif t=="table" then elseif t=="table" then
local acc = { } local acc = { }
local idx_dumped = { } local idx_dumped = { }
@ -164,17 +166,31 @@ end
-- http://stackoverflow.com/questions/5958818/loading-serialized-data-into-a-table -- http://stackoverflow.com/questions/5958818/loading-serialized-data-into-a-table
-- --
local function stringtotable(sdata) local env = {
loadstring = loadstring,
}
local function noop() end
local safe_env = {
loadstring = noop,
}
local function stringtotable(sdata, safe)
if sdata:byte(1) == 27 then return nil, "binary bytecode prohibited" end if sdata:byte(1) == 27 then return nil, "binary bytecode prohibited" end
local f, message = assert(loadstring(sdata)) local f, message = assert(loadstring(sdata))
if not f then return nil, message end if not f then return nil, message end
setfenv(f, table) if safe then
setfenv(f, safe_env)
else
setfenv(f, env)
end
return f() return f()
end end
function minetest.deserialize(sdata) function minetest.deserialize(sdata, safe)
local table = {} local table = {}
local okay,results = pcall(stringtotable, sdata) local okay, results = pcall(stringtotable, sdata, safe)
if okay then if okay then
return results return results
end end