Lua 5.3.2
我有一个用Lua / C编写的服务,它在同一个Lua_State中执行lua文件。
我需要为文件执行环境提供所有标准库。
最简单的方法是以这种方式执行文件:loadfile(file_path, "bt", _G)
问题是:文件中的代码能够破坏服务的全局状态,因此这种方法不安全。
因此,我需要创建一个沙盒环境loadfile(file_path, "bt", env)
问题:如何在env
变量中注册linit.c中的所有标准库?
我可以简单地注册linit.c中的所有lib,除了luaopen_base,因为它包含lua_pushglobaltable
我想到了这个:
local env = {}
for k,v in pairs(_G) do
if type(v)=="function" then
env[k] = v
end
end
但这看起来像是一个可悲的决定。有人有更好的解决方案吗?
答案 0 :(得分:4)
最简单的方法是让env
继承_G
:
setmetatable(env,{__index=_G})
_G
中的所有内容都会在env
中看到,但如果您通过创建全局变量来写env
,则不会影响_G
,似乎是你想要的。
不幸的是,_G
本身可以在_G
中看到,因此可以通过执行_G.print=anyvalue
等操作来写入原始环境。
要保护_G
,请添加:
env._G = env
不幸的是,原_G
仍可通过package.loaded._G
获取。如果您想要访问package
,则很难保护。最简单的方法是将_G.package
深度复制到env.package
并更改env.package.loaded._G=env
。