在Lua中重新创建setfenv()5.2

前端之家收集整理的这篇文章主要介绍了在Lua中重新创建setfenv()5.2前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何在Lua 5.2中重新创建setfenv的功能?我正在弄清楚你应该如何使用新的_ENV环境变量.

在Lua 5.1中,您可以使用setfenv来轻松地沙箱任何功能.

  1. --# Lua 5.1
  2.  
  3. print('_G',_G) -- address of _G
  4.  
  5. local foo = function()
  6. print('env',_G) -- address of sandBox _G
  7. bar = 1
  8. end
  9.  
  10. -- create a simple sandBox
  11. local env = { print = print }
  12. env._G = env
  13.  
  14. -- set the environment and call the function
  15. setfenv(foo,env)
  16. foo()
  17.  
  18. -- we should have global in our environment table but not in _G
  19. print(bar,env.bar)

运行此示例显示一个输出

  1. _G table: 0x62d6b0
  2. env table: 0x635d00
  3. nil 1

我想在Lua 5.2中重现这个简单的例子.下面是我的尝试,但它不像上面的例子那样工作.

  1. --# Lua 5.2
  2.  
  3. local function setfenv(f,env)
  4. local _ENV = env or {} -- create the _ENV upvalue
  5. return function(...)
  6. print('upvalue',_ENV) -- address of _ENV upvalue
  7. return f(...)
  8. end
  9. end
  10.  
  11. local foo = function()
  12. print('_ENV',_ENV) -- address of function _ENV
  13. bar = 1
  14. end
  15.  
  16. -- create a simple sandBox
  17. local env = { print = print }
  18. env._G = env
  19.  
  20. -- set the environment and call the function
  21. foo_env = setfenv(foo,env)
  22. foo_env()
  23.  
  24. -- we should have global in our envoirnment table but not in _G
  25. print(bar,env.bar)

运行此示例显示输出

  1. upvalue table: 0x637e90
  2. _ENV table: 0x6305f0
  3. 1 nil

我知道关于这个问题的其他几个问题,但是他们大多数似乎正在处理使用Lua 5.2中提供的新的加载功能加载动态代码(文件或字符串).在这里,我特别要求在沙箱中运行任意函数解决方案.我想这样做,而不使用调试库.根据Lua documentation,我们不应该依赖它.

解决方法

在Lua 5.2中不使用Lua的调试库,您无法更改功能的环境.一旦创建了一个函数,那就是它所具有的环境.修改此环境的唯一方法修改它的第一个upvalue,这需要调试库.

Lua 5.2环境的一般思想是,环境应该被认为是不可思议的(即:调试库).在环境中创建一个函数;一旦在那里创建,那就是它所拥有的环境.永远.

这是Lua 5.1中经常使用环境的方式,但是通过随意的函数调用修改任何东西的环境是很容易和认可的.如果您的Lua解释器删除了setfenv(以防止用户打破沙箱),则用户代码无法在内部为其自己的功能设置环境.所以外面的世界得到一个沙盒,但内部世界不能在沙箱内有沙盒.

Lua 5.2机制使得在功能创建之后修改环境变得更加困难,但它允许您在创建过程中设置环境.这可以让你在沙箱内沙箱.

所以你真正想要的是重新排列你的代码,如下所示:

  1. local foo;
  2.  
  3. do
  4. local _ENV = { print = print }
  5.  
  6. function foo()
  7. print('env',_ENV)
  8. bar = 1
  9. end
  10. end

foo现在沙盒了.而现在,有一个人打破沙盒比较困难.

你可以想像,这引起了Lua开发者的一些争论.

猜你在找的Lua相关文章