kong--kong
118 行
2.5 KiB
Lua
118 行
2.5 KiB
Lua
local clone = require "table.clone"
|
|
|
|
|
|
local setmetatable = setmetatable
|
|
local rawset = rawset
|
|
local unpack = table.unpack
|
|
local assert = assert
|
|
local error = error
|
|
local pairs = pairs
|
|
local pcall = pcall
|
|
local type = type
|
|
local load = load
|
|
local pack = table.pack
|
|
|
|
|
|
local function get_lua_env()
|
|
return require("kong.tools.sandbox.environment").lua
|
|
end
|
|
|
|
|
|
local function get_schema_env()
|
|
return require("kong.tools.sandbox.environment").schema
|
|
end
|
|
|
|
|
|
local function get_handler_env()
|
|
return require("kong.tools.sandbox.environment").handler
|
|
end
|
|
|
|
|
|
local function create_lua_env(env)
|
|
local new_env = clone(get_lua_env())
|
|
if env then
|
|
for k, v in pairs(new_env) do
|
|
rawset(new_env, k, env[k] ~= nil and env[k] or v)
|
|
end
|
|
if env.require ~= nil then
|
|
rawset(new_env, "require", env.require)
|
|
end
|
|
setmetatable(new_env, { __index = env })
|
|
end
|
|
return new_env
|
|
end
|
|
|
|
|
|
local function wrap(compiled)
|
|
return function(...)
|
|
local t = pack(pcall(compiled, ...))
|
|
if not t[1] then
|
|
return error(t[2], -1)
|
|
end
|
|
return unpack(t, 2, t.n)
|
|
end
|
|
end
|
|
|
|
|
|
local function protect_backward_compatible(chunk, chunkname, mode, env)
|
|
assert(type(chunk) == "string", "expected a string")
|
|
local compiled, err = load(chunk, chunkname, mode or "t", create_lua_env(env))
|
|
if not compiled then
|
|
return error(err, -1)
|
|
end
|
|
local fn = wrap(compiled)
|
|
return fn
|
|
end
|
|
|
|
|
|
local sandbox = {}
|
|
|
|
|
|
function sandbox.protect(chunk, chunkname_or_options, mode, env)
|
|
if type(chunkname_or_options) == "table" then
|
|
return protect_backward_compatible(chunk, nil, nil, chunkname_or_options and chunkname_or_options.env)
|
|
end
|
|
return protect_backward_compatible(chunk, chunkname_or_options, mode, env)
|
|
end
|
|
|
|
|
|
function sandbox.run(chunk, options, ...)
|
|
return sandbox.protect(chunk, options)(...)
|
|
end
|
|
|
|
|
|
local function protect(chunk, chunkname, env)
|
|
assert(type(chunk) == "string", "expected a string")
|
|
local compiled, err = load(chunk, chunkname, "t", env)
|
|
if not compiled then
|
|
return error(err, -1)
|
|
end
|
|
return compiled
|
|
end
|
|
|
|
|
|
function sandbox.protect_lua(chunk, chunkname)
|
|
return protect(chunk, chunkname, get_lua_env())
|
|
end
|
|
|
|
|
|
function sandbox.protect_schema(chunk, chunkname)
|
|
return protect(chunk, chunkname, get_schema_env())
|
|
end
|
|
|
|
|
|
function sandbox.protect_handler(chunk, chunkname)
|
|
return protect(chunk, chunkname, get_handler_env())
|
|
end
|
|
|
|
|
|
-- make sandbox(f) == sandbox.protect(f)
|
|
setmetatable(sandbox, {
|
|
__call = function(_, chunk, chunkname_or_options, mode, env)
|
|
return sandbox.protect(chunk, chunkname_or_options, mode, env)
|
|
end
|
|
})
|
|
|
|
|
|
return sandbox
|