mirror of
https://github.com/kikito/lua-sandbox.git
synced 2024-12-18 03:04:20 +00:00
initial version
This commit is contained in:
commit
31bac65e68
46
sandbox.lua
Normal file
46
sandbox.lua
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
local BASE_ENV = {}
|
||||||
|
|
||||||
|
([[
|
||||||
|
assert ipairs next pairs pcall tonumber tostring unpack select type _VERSION xpcall
|
||||||
|
|
||||||
|
string.byte string.char string.find string.format string.gmatch string.gsub
|
||||||
|
string.len string.lower string.match string.reverse string.sub string.upper
|
||||||
|
|
||||||
|
table.insert table.maxn table.remove table.sort
|
||||||
|
|
||||||
|
math.abs math.acos math.asin math.atan math.atan2 math.ceil math.cos
|
||||||
|
math.cosh math.deg math.exp math.foor math.fmod math.frexp math.huge
|
||||||
|
math.ldexp math.log math.log10 math.max math.min math.modf math.pi
|
||||||
|
math.pow math.rad math.random math.sin math.sinh math.sqrt math.tan
|
||||||
|
math.tanh
|
||||||
|
|
||||||
|
os.clock os.difftime os.time
|
||||||
|
]]):gsub('%S+', function(id)
|
||||||
|
local package, method = id:match('([^%.]+)%.([^%.]+)')
|
||||||
|
if package then
|
||||||
|
BASE_ENV[package] = BASE_ENV[package] or {}
|
||||||
|
BASE_ENV[package][method] = _G[package][method]
|
||||||
|
else
|
||||||
|
BASE_ENV[id] = _G[id]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local string_rep = string.rep
|
||||||
|
|
||||||
|
|
||||||
|
local function run(f, options)
|
||||||
|
if type(f) == 'string' then f = loadstring(f) end
|
||||||
|
|
||||||
|
string.rep = nil
|
||||||
|
setfenv(f, BASE_ENV)
|
||||||
|
local result = f()
|
||||||
|
|
||||||
|
string.rep = string_rep
|
||||||
|
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
local sandbox = { run = run }
|
||||||
|
|
||||||
|
|
||||||
|
return setmetatable(sandbox, {__call = function(_,f) return run(f) end})
|
38
spec/sandbox_spec.lua
Normal file
38
spec/sandbox_spec.lua
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
local sandbox = require 'sandbox'
|
||||||
|
|
||||||
|
describe('sandbox', function()
|
||||||
|
|
||||||
|
it('can run harmless functions', function()
|
||||||
|
local r = sandbox(function() return 'hello' end)
|
||||||
|
assert.equal(r, 'hello')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('can run harmless strings', function()
|
||||||
|
local r = sandbox("return 'hello'")
|
||||||
|
assert.equal(r, 'hello')
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('has access to safe methods', function()
|
||||||
|
assert.equal(10, sandbox("return tonumber('10')"))
|
||||||
|
assert.equal('HELLO', sandbox("return string.upper('hello')"))
|
||||||
|
assert.equal(1, sandbox("local a = {3,2,1}; table.sort(a); return a[1]"))
|
||||||
|
assert.equal(10, sandbox("return math.max(1,10)"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('does not allow access to not-safe stuff', function()
|
||||||
|
assert.has_error(function() sandbox('return setmetatable({}, {})') end)
|
||||||
|
assert.has_error(function() sandbox('return string.rep("hello", 5)') end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('does not allow pesky string:rep', function()
|
||||||
|
assert.has_error(function() sandbox('return ("hello"):rep(5)') end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('restores the value of string.rep', function()
|
||||||
|
sandbox("")
|
||||||
|
assert.equal('hellohello', string.rep('hello', 2))
|
||||||
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end)
|
Loading…
Reference in New Issue
Block a user