Add support for function serialization to minetest.serialize
authorShadowNinja <shadowninja@minetest.net>
Wed, 23 Apr 2014 21:21:17 +0000 (17:21 -0400)
committerShadowNinja <shadowninja@minetest.net>
Sun, 27 Apr 2014 20:15:53 +0000 (16:15 -0400)
builtin/serialize.lua

index 165cc6731894e75ab89a7b72a18a4f34314b8541..93fffe80d8e90888a8d20deff879fa9c81514ab7 100644 (file)
@@ -112,6 +112,8 @@ function minetest.serialize(x)
                elseif t=="number"   then return tostring(x)
                elseif t=="string"   then return string.format("%q", x)
                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
                        local acc        = { }
                        local idx_dumped = { }
@@ -164,17 +166,31 @@ end
 -- 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
        local f, message = assert(loadstring(sdata))
        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()
 end
 
-function minetest.deserialize(sdata)
+function minetest.deserialize(sdata, safe)
        local table = {}
-       local okay,results = pcall(stringtotable, sdata)
+       local okay, results = pcall(stringtotable, sdata, safe)
        if okay then
                return results
        end