Here is a solution for Lua 5.2 (including an example environment that will also work in 5.1):
-- save a pointer to globals that would be unreachable in sandbox local e=_ENV -- sample sandbox environment sandbox_env = { ipairs = ipairs, next = next, pairs = pairs, pcall = pcall, tonumber = tonumber, tostring = tostring, type = type, unpack = unpack, coroutine = { create = coroutine.create, resume = coroutine.resume, running = coroutine.running, status = coroutine.status, wrap = coroutine.wrap }, string = { byte = string.byte, char = string.char, find = string.find, format = string.format, gmatch = string.gmatch, gsub = string.gsub, len = string.len, lower = string.lower, match = string.match, rep = string.rep, reverse = string.reverse, sub = string.sub, upper = string.upper }, table = { insert = table.insert, maxn = table.maxn, remove = table.remove, sort = table.sort }, math = { abs = math.abs, acos = math.acos, asin = math.asin, atan = math.atan, atan2 = math.atan2, ceil = math.ceil, cos = math.cos, cosh = math.cosh, deg = math.deg, exp = math.exp, floor = math.floor, fmod = math.fmod, frexp = math.frexp, huge = math.huge, ldexp = math.ldexp, log = math.log, log10 = math.log10, max = math.max, min = math.min, modf = math.modf, pi = math.pi, pow = math.pow, rad = math.rad, random = math.random, sin = math.sin, sinh = math.sinh, sqrt = math.sqrt, tan = math.tan, tanh = math.tanh }, os = { clock = os.clock, difftime = os.difftime, time = os.time }, } function run_sandbox(sb_env, sb_func, ...) local sb_orig_env=_ENV if (not sb_func) then return nil end _ENV=sb_env local sb_ret={e.pcall(sb_func, ...)} _ENV=sb_orig_env return e.table.unpack(sb_ret) end
Then, to use it, you call your function ( my_func ) as follows:
pcall_rc, result_or_err_msg = run_sandbox(sandbox_env, my_func, arg1, arg2)