Recreating setfenv() in Lua 5.2

前端 未结 4 1099
长发绾君心
长发绾君心 2020-12-28 09:44

How can I recreate the functionality of setfenv in Lua 5.2? I\'m having some trouble understanding exactly how you are supposed to use the new _ENV

4条回答
  •  醉话见心
    2020-12-28 10:27

    You cannot change the environment of a function without using the debug library from Lua in Lua 5.2. Once a function has been created, that is the environment it has. The only way to modify this environment is by modifying its first upvalue, which requires the debug library.

    The general idea with environments in Lua 5.2 is that the environment should be considered immutable outside of trickery (ie: the debug library). You create a function in an environment; once created there, that's the environment it has. Forever.

    This is how environments were often used in Lua 5.1, but it was easy and sanctioned to modify the environment of anything with a casual function call. And if your Lua interpreter removed setfenv (to prevent users from breaking the sandbox), then the user code can't set the environment for their own functions internally. So the outside world gets a sandbox, but the inside world can't have a sandbox within the sandbox.

    The Lua 5.2 mechanism makes it harder to modify the environment post function-creation, but it does allow you to set the environment during creation. Which lets you sandbox inside the sandbox.

    So what you really want is to just rearrange your code like this:

    local foo;
    
    do
      local _ENV = { print = print }
    
      function foo()
        print('env', _ENV)
        bar = 1
      end
    end
    

    foo is now sandboxed. And now, it's much harder for someone to break the sandbox.

    As you can imagine, this has caused some contention among Lua developers.

提交回复
热议问题