【问题标题】:LuaJIT setfenv not appearing to set further function calls to the given environmentLuaJIT setfenv 似乎没有对给定环境设置进一步的函数调用
【发布时间】:2016-12-31 02:44:32
【问题描述】:

我正在尝试使用 setfenv 对某些函数进行沙箱处理,我收到以下输出:

123
nil

为什么调用sandboxTest()nil时是testValue,而在callSandboxedTest()中访问却是123?

使用 LuaJIT 2.1.0-beta2 (Lua 5.1)

function sandboxTest()
    print(testValue)
end

local aNumber = 123

function callSandboxedTest()
    setfenv(1, {
        print = print,
        testValue = aNumber,
        sandboxTest = sandboxTest
    })
    print(testValue)
    sandboxTest()
end

callSandboxedTest()

【问题讨论】:

    标签: lua luajit


    【解决方案1】:

    环境不是调用堆栈的一部分。每个函数都有其自己的环境。所以sandboxTest 有一个环境,callSandboxTest 也是如此。改变一个函数的环境不会影响另一个函数的环境。

    sandboxTest 将继续使用默认环境,因此它会访问常规全局表以查找testValue。由于testValue 从未在全局表中设置,sandboxTest 将得到nil

    这就是为什么在维护沙盒时,仔细选择向沙盒公开哪些功能非常重要。如果某个函数需要成为沙箱的一部分,则该函数需要设置其环境。

    这就是为什么最好基于编译的 Lua 块而不是单个函数来沙箱。创建函数时,创建的函数会继承当前环境。

    【讨论】:

      【解决方案2】:

      你没有修改sandboxTest使用的环境;您只修改了当前函数的环境。您可以使用setfenv通过传递函数名称来设置特定函数的环境(传递数字会修改调用堆栈中函数的环境):

      setfenv(sandboxTest, {
              print = print,
              testValue = aNumber,
              sandboxTest = sandboxTest
          })
      

      这将打印123 123

      【讨论】:

        猜你喜欢
        • 2016-01-11
        • 1970-01-01
        • 2015-12-15
        • 2020-01-26
        • 2012-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-16
        相关资源
        最近更新 更多