sandbox.lua/spec/sandbox_spec.lua

146 lines
5.0 KiB
Lua
Raw Normal View History

2013-09-02 20:11:33 +00:00
local sandbox = require 'sandbox'
2013-09-05 22:40:43 +00:00
describe('sandbox.run', function()
2013-09-02 20:11:33 +00:00
2013-09-05 22:40:43 +00:00
describe('when handling base cases', function()
2013-09-02 20:11:33 +00:00
2013-09-05 22:40:43 +00:00
it('can run harmless strings', function()
local r = sandbox.run("return 'hello'")
assert.equal(r, 'hello')
2013-09-05 22:40:43 +00:00
end)
2013-09-02 20:11:33 +00:00
if sandbox.bytecode_blocked then
it('rejects bytecode', function()
local fn = function() end
assert.error(function() sandbox.run(string.dump(fn)) end)
end)
else
it('accepts bytecode (PUC Rio 5.1)', function()
local fn = function() end
assert.has.no.error(function() sandbox.run(string.dump(fn)) end)
end)
end
2013-09-05 22:40:43 +00:00
it('has access to safe methods', function()
assert.equal(10, sandbox.run("return tonumber('10')"))
assert.equal('HELLO', sandbox.run("return string.upper('hello')"))
assert.equal(1, sandbox.run("local a = {3,2,1}; table.sort(a); return a[1]"))
assert.equal(10, sandbox.run("return math.max(1,10)"))
2013-09-05 22:40:43 +00:00
end)
2013-09-02 20:11:33 +00:00
2013-09-05 22:40:43 +00:00
it('does not allow access to not-safe stuff', function()
assert.error(function() sandbox.run('return setmetatable({}, {})') end)
assert.error(function() sandbox.run('return string.rep("hello", 5)') end)
2013-09-05 22:40:43 +00:00
end)
2020-12-13 17:54:40 +00:00
it('does return multiple values', function()
local result = { sandbox.run("return 'hello', 'world'") }
assert.same({ 'hello', 'world' }, result)
end)
2013-09-02 20:11:33 +00:00
end)
2013-09-05 22:40:43 +00:00
describe('when handling string.rep', function()
it('does not allow pesky string:rep', function()
assert.error(function() sandbox.run('return ("hello"):rep(5)') end)
2013-09-05 22:40:43 +00:00
end)
2013-09-02 20:11:33 +00:00
2013-09-05 22:40:43 +00:00
it('restores the value of string.rep', function()
sandbox.run("")
assert.equal('hellohello', string.rep('hello', 2))
2013-09-05 22:40:43 +00:00
end)
it('restores string.rep even if there is an error', function()
assert.error(function() sandbox.run("error('foo')") end)
assert.equal('hellohello', string.rep('hello', 2))
2013-09-05 22:40:43 +00:00
end)
2013-09-02 20:11:33 +00:00
it('passes parameters to the code', function()
assert.equal(sandbox.run("local a, b = ...; return a + b", {}, 1,2), 3)
2013-09-05 22:40:43 +00:00
end)
2013-09-03 09:53:41 +00:00
end)
2013-09-05 22:40:43 +00:00
describe('when the sandboxed code tries to modify the base environment', function()
2013-09-05 22:40:43 +00:00
it('does not allow modifying the modules', function()
assert.error(function() sandbox.run("string.foo = 1") end)
assert.error(function() sandbox.run("string.char = 1") end)
2013-09-05 22:40:43 +00:00
end)
it('does not persist modifications of base functions', function()
sandbox.run('error = function() end')
assert.error(function() sandbox.run("error('this should be raised')") end)
2013-09-05 22:40:43 +00:00
end)
it('does not persist modification to base functions even when they are provided by the base env', function()
2013-09-05 22:40:43 +00:00
local env = {['next'] = 'hello'}
sandbox.run('next = "bye"', { env=env })
assert.equal(env['next'], 'hello')
2013-09-05 22:40:43 +00:00
end)
end)
2013-09-03 10:53:26 +00:00
if sandbox.quota_supported then
describe('when given infinite loops', function()
it('throws an error with infinite loops', function()
assert.error(function() sandbox.run("while true do end") end)
end)
2013-09-03 11:20:38 +00:00
it('restores string.rep even after a while true', function()
assert.error(function() sandbox.run("while true do end") end)
assert.equal('hellohello', string.rep('hello', 2))
end)
2013-09-02 20:11:33 +00:00
it('accepts a quota param', function()
assert.has_no.errors(function() sandbox.run("for i=1,100 do end") end)
assert.error(function() sandbox.run("for i=1,100 do end", {quota = 20}) end)
end)
2013-09-03 11:20:38 +00:00
it('does not use quotes if the quote param is false', function()
assert.has_no.errors(function() sandbox.run("for i=1,1000000 do end", {quota = false}) end)
end)
2013-09-03 11:14:42 +00:00
end)
else
it('throws an error when trying to use the quota option in an unsupported environment (LuaJIT)', function()
assert.error(function() sandbox.run("", {quota = 20}) end)
end)
end
2013-09-02 20:11:33 +00:00
2013-09-05 22:40:43 +00:00
2013-09-03 16:07:03 +00:00
describe('when given an env option', function()
it('is available on the sandboxed env as the _G variable', function()
local env = {foo = 1}
assert.equal(1, sandbox.run("return foo", {env = env}))
assert.equal(1, sandbox.run("return _G.foo", {env = env}))
2013-09-03 14:41:46 +00:00
end)
2013-09-03 16:07:03 +00:00
it('does not hide base env', function()
assert.equal('HELLO', sandbox.run("return string.upper(foo)", {env = {foo = 'hello'}}))
2013-09-03 14:41:46 +00:00
end)
2013-09-03 16:07:03 +00:00
it('cannot modify the env', function()
2013-09-03 16:07:03 +00:00
local env = {foo = 1}
2013-09-05 22:40:43 +00:00
sandbox.run("foo = 2", {env = env})
assert.equal(env.foo, 1)
end)
it('uses the env metatable, if it exists', function()
local env1 = { foo = 1 }
local env2 = { bar = 2 }
setmetatable(env2, { __index = env1 })
assert.equal(3, sandbox.run("return foo + bar", { env = env2 }))
end)
it('can override the base env', function()
local env = { tostring = function(x) return "hello " .. x end }
assert.equal("hello peter", sandbox.run("return tostring('peter')", { env = env }))
2013-09-03 16:07:03 +00:00
end)
it('can override the base env with false', function()
local env = { tostring = false }
assert.equal(false, sandbox.run("return tostring", { env = env }))
end)
2013-09-03 16:07:03 +00:00
end)
2013-09-02 20:11:33 +00:00
end)