LuaJIT setfenv не появляется для установки дальнейших вызовов функций в данной среде

Я пытаюсь изолировать некоторые функции с помощью setfenv и получаю следующий вывод:

123
nil

Почему testValue при звонке sandboxTest()nil, но это 123, когда к нему обращаются в callSandboxedTest()?

Использование LuaJIT 2.1.0-бета2 (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()

2 ответа

Решение

Среды не являются частью стека вызовов. Каждая функция имеет свою среду. Так sandboxTest имеет среду, как и callSandboxTest, Изменение среды одной функции не влияет на среду другой.

sandboxTest будет продолжать использовать среду по умолчанию, поэтому он будет обращаться к обычной глобальной таблице, чтобы найти testValue, И с тех пор testValue никогда не устанавливается в глобальной таблице, sandboxTest получите nil,

Вот почему при обслуживании песочницы очень важно тщательно выбирать, какие функции следует выставлять в песочницу. Если функция должна быть частью песочницы, то для этой функции должна быть установлена ​​среда.

Вот почему лучше использовать песочницу на основе скомпилированных фрагментов Lua, а не отдельных функций. При создании функций созданные функции наследуют текущую среду.

Вы не изменили среду, которая sandboxTest использует; Вы только изменили среду текущей функции. Ты можешь использовать setfenv установить среду конкретной функции, передав имя функции (передача числа изменяет среду функции в стеке вызовов):

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

Это напечатает 123 123,

Другие вопросы по тегам