Lua沙盒_ENV与个人baselib(需要,断言等)

时间:2016-01-05 01:00:49

标签: lua sandbox lua-api

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

但这看起来像是一个可悲的决定。有人有更好的解决方案吗?

1 个答案:

答案 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