69 lines
1.9 KiB
Lua
69 lines
1.9 KiB
Lua
local log = buildat:Logger("__client/sandbox")
|
|
|
|
local buildat_safe_list = {
|
|
"Logger",
|
|
}
|
|
|
|
local buildat_safe = {}
|
|
|
|
for _, name in ipairs(buildat_safe_list) do
|
|
buildat_safe[name] = buildat[name]
|
|
end
|
|
|
|
local sandbox = {}
|
|
|
|
sandbox.buildat = buildat
|
|
|
|
sandbox.require = function(name)
|
|
log:info("require(\""..name.."\")")
|
|
-- Check loaded modules
|
|
if package.loaded[name] then
|
|
local unsafe = package.loaded[name]
|
|
if type(unsafe.safe) ~= 'table' then
|
|
error("require: \""..name.."\" didn't return safe interface")
|
|
end
|
|
return unsafe.safe
|
|
end
|
|
-- Allow loading extensions
|
|
local m = string.match(name, '^buildat/extension/([a-zA-Z0-9_]+)$')
|
|
if m then
|
|
local unsafe = __buildat_load_extension(m)
|
|
if unsafe == nil then
|
|
error("require: Extension not found: \""..m.."\"")
|
|
end
|
|
package.loaded[name] = unsafe
|
|
if type(unsafe.safe) ~= 'table' then
|
|
error("require: \""..name.."\" didn't return safe interface")
|
|
end
|
|
log:info("Loaded extension \""..name.."\"")
|
|
return unsafe.safe
|
|
end
|
|
-- Disallow loading anything else
|
|
error("require: \""..name.."\" not found in sandbox")
|
|
end
|
|
|
|
local function run_in_sandbox(untrusted_code, sandbox)
|
|
if untrusted_code:byte(1) == 27 then return nil, "binary bytecode prohibited" end
|
|
local untrusted_function, message = loadstring(untrusted_code)
|
|
if not untrusted_function then return nil, message end
|
|
setfenv(untrusted_function, sandbox)
|
|
return pcall(untrusted_function)
|
|
end
|
|
|
|
function buildat:run_script_file(name)
|
|
local code = __buildat_get_file_content(name)
|
|
if not code then
|
|
log:error("Failed to load script file: "+name)
|
|
return false
|
|
end
|
|
log:info("buildat:run_script_file("..name.."): #code="..#code)
|
|
local status, err = run_in_sandbox(code, sandbox)
|
|
--local status, err = run_in_sandbox(
|
|
-- [[buildat:Logger("foo"):info("Pihvi")]], sandbox)
|
|
if status == false then
|
|
log:error("Failed to run script: "..err)
|
|
return false
|
|
end
|
|
return true
|
|
end
|