lualuajitsol3

Require but dont break out of sandbox environment - luajit


Is there a way to run a script in a sandbox environment to not pollute global state, but still be able to require"someluafile" in which global vars get set for said environment and NOT the global state

-- main script
local moduleXY = require"moduleXY"
v = 0
moduleXY.setV()

-- moduleXY
local function setV ()
  v = 42
end

local moduleXY = {
   setV = setV
}

return moduleXY

so that after the call the states v is nil and envs v is set to 42 (instead of state v being 42 and envs 0)

luajit (so 5.1), cpp binding sol3


Solution

  • Lua 5.1 uses setfenv to change the environment of a function. Here's an example.

    local moduleXY = require"moduleXY"
    v = 0
    
    env = setmetatable({}, {__index = _G}) -- create an environment
    setfenv(moduleXY.setV, env) -- change the environment
    moduleXY.setV()
    print(v)     -- 0
    print(env.v) -- 42
    
    setfenv(moduleXY.setV, _G)  -- revert the environment
    moduleXY.setV()
    print(v)     -- 42
    

    To change the environment of the current thread use setfenv(0).

    setfenv(0, env) -- this doesn't affect loaded functions
    local moduleXY = require"moduleXY" -- module is loaded in 'env' environment
    moduleXY.setV()
    print(env.v) -- 42
    
    setfenv(0, getfenv()) -- revert the thread environment
    require"othermodule" -- load other module in default environment