mirror of
https://github.com/pkulchenko/serpent.git
synced 2024-11-21 23:24:24 +00:00
Added setting env to protect against assigning global functions (closes #15).
This commit is contained in:
parent
ce5281c1f5
commit
3fcbb72531
@ -1,4 +1,4 @@
|
|||||||
local n, v = "serpent", 0.273 -- (C) 2012-15 Paul Kulchenko; MIT License
|
local n, v = "serpent", 0.279 -- (C) 2012-15 Paul Kulchenko; MIT License
|
||||||
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
local c, d = "Paul Kulchenko", "Lua serializer and pretty printer"
|
||||||
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
local snum = {[tostring(1/0)]='1/0 --[[math.huge]]',[tostring(-1/0)]='-1/0 --[[-math.huge]]',[tostring(0/0)]='0/0'}
|
||||||
local badtype = {thread = true, userdata = true, cdata = true}
|
local badtype = {thread = true, userdata = true, cdata = true}
|
||||||
@ -103,12 +103,33 @@ local function s(t, opts)
|
|||||||
return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end"
|
return not name and body..warn or "do local "..body..sepr..tail.."return "..name..sepr.."end"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not setfenv then -- Lua 5.2+
|
||||||
|
-- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
|
||||||
|
-- this assumes f is a function
|
||||||
|
local function findenv(f)
|
||||||
|
local level = 1
|
||||||
|
repeat
|
||||||
|
local name, value = debug.getupvalue(f, level)
|
||||||
|
if name == '_ENV' then return level, value end
|
||||||
|
level = level + 1
|
||||||
|
until name == nil
|
||||||
|
return nil end
|
||||||
|
getfenv = function (f) return(select(2, findenv(f)) or _G) end
|
||||||
|
setfenv = function (f, t)
|
||||||
|
local level = findenv(f)
|
||||||
|
if level then debug.setupvalue(f, level, t) end
|
||||||
|
return f end
|
||||||
|
end
|
||||||
|
|
||||||
local function deserialize(data, opts)
|
local function deserialize(data, opts)
|
||||||
local f, res = (loadstring or load)('return '..data)
|
local f, res = (loadstring or load)('return '..data)
|
||||||
if not f then f, res = (loadstring or load)(data) end
|
if not f then f, res = (loadstring or load)(data) end
|
||||||
if not f then return f, res end
|
if not f then return f, res end
|
||||||
if opts and opts.safe == false then return pcall(f) end
|
if opts and opts.safe == false then return pcall(f) end
|
||||||
|
|
||||||
|
local env = {}
|
||||||
|
env._G = setmetatable(env, { __index = getfenv(f) })
|
||||||
|
f = setfenv(f, env)
|
||||||
local count, thread = 0, coroutine.running()
|
local count, thread = 0, coroutine.running()
|
||||||
local h, m, c = debug.gethook(thread)
|
local h, m, c = debug.gethook(thread)
|
||||||
debug.sethook(function (e, l) count = count + 1
|
debug.sethook(function (e, l) count = count + 1
|
||||||
|
19
t/test.lua
19
t/test.lua
@ -392,6 +392,25 @@ do -- test for Lua 5.2 compiled without loadstring
|
|||||||
assert(_a[1]() == a[1](), "deserialization of function value without loadstring (2/2): failed")
|
assert(_a[1]() == a[1](), "deserialization of function value without loadstring (2/2): failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local ok, res = serpent.load("do error('not allowed') end")
|
||||||
|
assert(not ok and res:find("cannot call functions"),
|
||||||
|
"not allowing calling functions from serialized content: failed")
|
||||||
|
|
||||||
|
local print = _G.print
|
||||||
|
local ok, res = serpent.load("do print = error end")
|
||||||
|
assert(ok and _G.print == print and print ~= error,
|
||||||
|
"not allowing resetting `print` from serialized content (1/3): failed")
|
||||||
|
|
||||||
|
local ok, res = serpent.load("do _G.print = error end")
|
||||||
|
assert(ok and _G.print == print and _G.print ~= error,
|
||||||
|
"not allowing resetting `print` from serialized content (2/3): failed")
|
||||||
|
|
||||||
|
local ok, res = serpent.load("do _G._G.print = error end")
|
||||||
|
assert(ok and _G.print == print and print ~= error,
|
||||||
|
"not allowing resetting `print` from serialized content (3/3): failed")
|
||||||
|
end
|
||||||
|
|
||||||
print("All tests passed.")
|
print("All tests passed.")
|
||||||
|
|
||||||
if arg[1] == 'perf' then
|
if arg[1] == 'perf' then
|
||||||
|
Loading…
Reference in New Issue
Block a user