lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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