Lua 5.2的setfenv()如何改写为长尾?
- 内容介绍
- 文章标签
- 相关推荐
本文共计812个文字,预计阅读时间需要4分钟。
在Lua 5.2中,您可以创建一个名为`setfenv`的新函数来重新构建其功能。以下是一个简化的示例:
luafunction setfenv(new_env, obj) local meta={__index=obj} return setmetatable(new_env, meta)end
_ENV={}_ENV.some_var=Hello, World!
local function test() print(_ENV.some_var)end
local my_env=setfenv(test, _ENV)test() -- 输出 Hello, World!
在Lua 5.1中,您可以使用`setfenv`来轻松地创建一个受限的环境:
lualocal function test() print(_ENV.some_var)end
local function restricted_function() local env={some_var=受限值} setfenv(test, env) test() -- 输出 受限值end
restricted_function()
如何在Lua 5.2中重新创建setfenv的功能?我正在弄清楚你应该如何使用新的_ENV环境变量.在Lua 5.1中,您可以使用setfenv来轻松地沙箱任何功能.
--# Lua 5.1 print('_G', _G) -- address of _G local foo = function() print('env', _G) -- address of sandbox _G bar = 1 end -- create a simple sandbox local env = { print = print } env._G = env -- set the environment and call the function setfenv(foo, env) foo() -- we should have global in our environment table but not in _G print(bar, env.bar)
运行此示例显示一个输出:
_G table: 0x62d6b0 env table: 0x635d00 nil 1
我想在Lua 5.2中重现这个简单的例子.下面是我的尝试,但它不像上面的例子那样工作.
--# Lua 5.2 local function setfenv(f, env) local _ENV = env or {} -- create the _ENV upvalue return function(...) print('upvalue', _ENV) -- address of _ENV upvalue return f(...) end end local foo = function() print('_ENV', _ENV) -- address of function _ENV bar = 1 end -- create a simple sandbox local env = { print = print } env._G = env -- set the environment and call the function foo_env = setfenv(foo, env) foo_env() -- we should have global in our envoirnment table but not in _G print(bar, env.bar)
运行此示例显示输出:
upvalue table: 0x637e90 _ENV table: 0x6305f0 1 nil
我知道关于这个问题的其他几个问题,但是他们大多数似乎正在处理使用Lua 5.2中提供的新的加载功能加载动态代码(文件或字符串).在这里,我特别要求在沙箱中运行任意函数的解决方案.我想这样做,而不使用调试库.根据Lua documentation,我们不应该依赖它.
在Lua 5.2中不使用Lua的调试库,您无法更改功能的环境.一旦创建了一个函数,那就是它所具有的环境.修改此环境的唯一方法是修改它的第一个upvalue,这需要调试库.Lua 5.2环境的一般思想是,环境应该被认为是不可思议的(即:调试库).在环境中创建一个函数;一旦在那里创建,那就是它所拥有的环境.永远.
这是Lua 5.1中经常使用环境的方式,但是通过随意的函数调用来修改任何东西的环境是很容易和认可的.如果您的Lua解释器删除了setfenv(以防止用户打破沙箱),则用户代码无法在内部为其自己的功能设置环境.所以外面的世界得到一个沙盒,但内部世界不能在沙箱内有沙盒.
Lua 5.2机制使得在功能创建之后修改环境变得更加困难,但它允许您在创建过程中设置环境.这可以让你在沙箱内沙箱.
所以你真正想要的是重新排列你的代码,如下所示:
local foo; do local _ENV = { print = print } function foo() print('env', _ENV) bar = 1 end end
foo现在沙盒了.而现在,有一个人打破沙盒比较困难.
你可以想像,这引起了Lua开发者的一些争论.
本文共计812个文字,预计阅读时间需要4分钟。
在Lua 5.2中,您可以创建一个名为`setfenv`的新函数来重新构建其功能。以下是一个简化的示例:
luafunction setfenv(new_env, obj) local meta={__index=obj} return setmetatable(new_env, meta)end
_ENV={}_ENV.some_var=Hello, World!
local function test() print(_ENV.some_var)end
local my_env=setfenv(test, _ENV)test() -- 输出 Hello, World!
在Lua 5.1中,您可以使用`setfenv`来轻松地创建一个受限的环境:
lualocal function test() print(_ENV.some_var)end
local function restricted_function() local env={some_var=受限值} setfenv(test, env) test() -- 输出 受限值end
restricted_function()
如何在Lua 5.2中重新创建setfenv的功能?我正在弄清楚你应该如何使用新的_ENV环境变量.在Lua 5.1中,您可以使用setfenv来轻松地沙箱任何功能.
--# Lua 5.1 print('_G', _G) -- address of _G local foo = function() print('env', _G) -- address of sandbox _G bar = 1 end -- create a simple sandbox local env = { print = print } env._G = env -- set the environment and call the function setfenv(foo, env) foo() -- we should have global in our environment table but not in _G print(bar, env.bar)
运行此示例显示一个输出:
_G table: 0x62d6b0 env table: 0x635d00 nil 1
我想在Lua 5.2中重现这个简单的例子.下面是我的尝试,但它不像上面的例子那样工作.
--# Lua 5.2 local function setfenv(f, env) local _ENV = env or {} -- create the _ENV upvalue return function(...) print('upvalue', _ENV) -- address of _ENV upvalue return f(...) end end local foo = function() print('_ENV', _ENV) -- address of function _ENV bar = 1 end -- create a simple sandbox local env = { print = print } env._G = env -- set the environment and call the function foo_env = setfenv(foo, env) foo_env() -- we should have global in our envoirnment table but not in _G print(bar, env.bar)
运行此示例显示输出:
upvalue table: 0x637e90 _ENV table: 0x6305f0 1 nil
我知道关于这个问题的其他几个问题,但是他们大多数似乎正在处理使用Lua 5.2中提供的新的加载功能加载动态代码(文件或字符串).在这里,我特别要求在沙箱中运行任意函数的解决方案.我想这样做,而不使用调试库.根据Lua documentation,我们不应该依赖它.
在Lua 5.2中不使用Lua的调试库,您无法更改功能的环境.一旦创建了一个函数,那就是它所具有的环境.修改此环境的唯一方法是修改它的第一个upvalue,这需要调试库.Lua 5.2环境的一般思想是,环境应该被认为是不可思议的(即:调试库).在环境中创建一个函数;一旦在那里创建,那就是它所拥有的环境.永远.
这是Lua 5.1中经常使用环境的方式,但是通过随意的函数调用来修改任何东西的环境是很容易和认可的.如果您的Lua解释器删除了setfenv(以防止用户打破沙箱),则用户代码无法在内部为其自己的功能设置环境.所以外面的世界得到一个沙盒,但内部世界不能在沙箱内有沙盒.
Lua 5.2机制使得在功能创建之后修改环境变得更加困难,但它允许您在创建过程中设置环境.这可以让你在沙箱内沙箱.
所以你真正想要的是重新排列你的代码,如下所示:
local foo; do local _ENV = { print = print } function foo() print('env', _ENV) bar = 1 end end
foo现在沙盒了.而现在,有一个人打破沙盒比较困难.
你可以想像,这引起了Lua开发者的一些争论.

