mirror of
https://github.com/kikito/lua-sandbox.git
synced 2024-12-18 03:04:20 +00:00
cleanup
This commit is contained in:
parent
36be73e3a9
commit
b1d69c89d7
30
sandbox.lua
30
sandbox.lua
@ -47,15 +47,26 @@ end)
|
|||||||
|
|
||||||
local string_rep = string.rep
|
local string_rep = string.rep
|
||||||
|
|
||||||
local function copy(other)
|
local copy -- defined below
|
||||||
|
|
||||||
|
local function merge(destination, other)
|
||||||
if type(other) ~= 'table' then return other end
|
if type(other) ~= 'table' then return other end
|
||||||
local c = {}
|
|
||||||
for k,v in pairs(other) do
|
for k,v in pairs(other) do
|
||||||
c[copy(k)] = copy(v)
|
destination[copy(k)] = copy(v)
|
||||||
end
|
end
|
||||||
|
return destination
|
||||||
|
end
|
||||||
|
|
||||||
|
-- declared above
|
||||||
|
copy = function(other)
|
||||||
|
if type(other) ~= 'table' then return other end
|
||||||
|
local c = merge({}, other)
|
||||||
|
local mt = getmetatable(other)
|
||||||
|
if mt then setmetatable(c, copy(mt)) end
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function cleanup()
|
local function cleanup()
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
string.rep = string_rep
|
string.rep = string_rep
|
||||||
@ -66,11 +77,12 @@ local function run(f, options)
|
|||||||
|
|
||||||
options = options or {}
|
options = options or {}
|
||||||
|
|
||||||
local limit = options.limit or 500000
|
local quota = options.quota or 500000
|
||||||
|
local env = options.env or {}
|
||||||
|
|
||||||
local env = copy(BASE_ENV)
|
local sandboxed_env = merge(copy(BASE_ENV), env)
|
||||||
|
|
||||||
setfenv(f, env)
|
setfenv(f, sandboxed_env)
|
||||||
|
|
||||||
-- I would love to be able to make step greater than 1
|
-- I would love to be able to make step greater than 1
|
||||||
-- (say, 500000) but any value > 1 seems to choke with a simple while true do end
|
-- (say, 500000) but any value > 1 seems to choke with a simple while true do end
|
||||||
@ -80,9 +92,9 @@ local function run(f, options)
|
|||||||
local instructions_count = 0
|
local instructions_count = 0
|
||||||
local timeout = function(str)
|
local timeout = function(str)
|
||||||
instructions_count = instructions_count + 1
|
instructions_count = instructions_count + 1
|
||||||
if instructions_count >= limit then
|
if instructions_count >= quota then
|
||||||
cleanup()
|
cleanup()
|
||||||
error('Quota exceeded: ' .. tostring(instructions_count) .. '/' .. tostring(limit) .. ' instructions')
|
error('Quota exceeded: ' .. tostring(instructions_count) .. '/' .. tostring(quota) .. ' instructions')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
debug.sethook(timeout, "", step)
|
debug.sethook(timeout, "", step)
|
||||||
@ -91,8 +103,8 @@ local function run(f, options)
|
|||||||
local ok, result = pcall(f)
|
local ok, result = pcall(f)
|
||||||
|
|
||||||
cleanup()
|
cleanup()
|
||||||
if not ok then error(result) end
|
|
||||||
|
|
||||||
|
if not ok then error(result) end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ describe('sandbox', function()
|
|||||||
it('does not allow access to not-safe stuff', function()
|
it('does not allow access to not-safe stuff', function()
|
||||||
assert.has_error(function() sandbox('return setmetatable({}, {})') end)
|
assert.has_error(function() sandbox('return setmetatable({}, {})') end)
|
||||||
assert.has_error(function() sandbox('return string.rep("hello", 5)') end)
|
assert.has_error(function() sandbox('return string.rep("hello", 5)') end)
|
||||||
|
assert.has_error(function() sandbox('return _G.string.upper("hello")') end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('does not allow pesky string:rep', function()
|
it('does not allow pesky string:rep', function()
|
||||||
@ -55,13 +56,23 @@ describe('sandbox', function()
|
|||||||
assert.equal('hellohello', string.rep('hello', 2))
|
assert.equal('hellohello', string.rep('hello', 2))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('#focus accepts a limit param', function()
|
it('accepts a quota param', function()
|
||||||
assert.no_has_error(function() sandbox("for i=1,100 do end") end)
|
assert.no_has_error(function() sandbox("for i=1,100 do end") end)
|
||||||
assert.has_error(function() sandbox("for i=1,100 do end", {limit = 50}) end)
|
assert.has_error(function() sandbox("for i=1,100 do end", {quota = 50}) end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
describe('when given an env', function()
|
||||||
|
it('is available on the sandboxed env', function()
|
||||||
|
assert.equal(1, sandbox("return foo", {env = {foo = 1}}))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('does not hide previous env', function()
|
||||||
|
assert.equal('HELLO', sandbox("return string.upper(foo)", {env = {foo = 'hello'}}))
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user