[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Sandbox in Lua 5.1
- From: "Francois Retief" <fgretief@...>
- Date: Tue, 27 May 2008 14:52:13 +0200
Hello all,
I have to convert a large set of Lua code from Lua 5.0 (with Compact-5.1) to
Lua 5.1
One of the things that has me stumped is the implementation of a sandbox.
The API more or less looks like this:
function Call( func )
local env = CreateSandbox() -- Create a copy of the current global
environment
local f = SandBox( func, env ) -- Wrap the function in a virtual
environment
return f() -- Call the function 'func' inside the
virtual environment
end
The idea behind this SandBox function is to restore the global environment to
the state it was in before the function was called. The function can modify
the global env to its harts content, but when it is finished, the global
environment is restored.
My problem comes in with the package management functions in 5.1. The Lua 5.0
code (see SandBox function below) depends on the old Compact-5.1
implementations that allow us to override the environment of these functions
(require/module/loaders). But in Lua 5.1 this can't be done due to their C
implementations.
So my question is: Do I need to write pure Lua implementations of the package
functions (require and module) so that I can override their environments? Or
is there an alternative way to do this kind of sandboxing in Lua 5.1?
-- Lua 5.0 (with compact-5.1) code.
function SandBox( f, sandbox )
local globalEnv = getfenv( 0 )
return function( ... )
-- Apply new environments to the relevant functions
local packageFunctions = {
require, module, sandbox.Environment.package.loaders
}
local fEnvs = GetFEnvs( packageFunctions ) -- Get a list of function
environments used by the functions.
SetFEnvs( packageFunctions, sandbox.PackageEnvironment ) -- Set the
environment for the functions.
setfenv( 0, sandbox.Environment )
setfenv( f, sandbox.Environment )
-- Call the function
local results = { xpcall( function() return f( unpack( arg )) end,
debug.traceback ) }
local callOk = table.remove( results, 1 )
-- Restore the environments of the functions
setfenv( 0, globalEnv )
RestoreFEnvs( fEnvs )
-- Return the function results
if not callOk then
error( results[1], 2 )
end
return unpack( results )
end
end
Cheers
Francois
E-mail Disclaimer
http://www.sunspace.co.za/emaildisclaimer.htm