名为type的全局变量隐藏了Lua中的内置type()函数

时间:2011-02-03 20:19:59

标签: c++ lua

我正在研究的一个C ++程序是使用lua进行配置。它使用硬编码脚本设置了几个lua函数:

luaL_loadbuffer(pmLuaState, headerscript, strlen(headerscript), "header script");

然后加载配置lua文件(调用前面提到的函数):

luaL_loadfile(pmLuaState, filename)

不幸的是,Lua配置文件使用名为type的全局变量,因此尝试从我的headerscript调用内置的type()函数失败并出现Lua错误:

attempt to call global 'type' (a string value)

由于我的方案的限制,我无法编辑有问题的配置文件。我想知道是否有一种方法可以说明我想要使用内置的type()函数。

我是Lua的新手,所以如果有更好的方法来加载这些脚本以避免这种全局隐藏问题,我会对它开放(但同样,我无法编辑配置脚本)。

Lua版本:5.1.4

2 个答案:

答案 0 :(得分:3)

你应该sandbox配置文件,这样它们就不会影响整个程序的全局环境。

使用空表作为luaL_load*()返回的块上的环境调用lua_setfenv()

更新:如果配置文件需要来自全局环境的东西,请用metatables公开它。

在Lua:

setfenv(chunk, setmetatable({__index = _G }))

(阅读手册以了解如何用C语言书写。)

请注意,这种沙盒方法对于不受信任的代码来说太弱了。例如,config可以执行table.concat = myevilfunction之类的操作。请参阅上面链接的Wiki页面,了解完整的沙盒方法(虽然在您的情况下应该是过度杀戮)。

答案 1 :(得分:3)

修改全局变量后,无法恢复该值 - 也就是说,必须首先阻止脚本设置_G.type,或者预先存储该值。第二个是相对微不足道的

local type = type -- problem solved

或者您可以使用环境来解决此问题。这是一个非常常见的脚本。

local loadedmodules = {}
import = function(filename)
    if (loadedmodules[filename]) then
        return loadedmodules[filename]
    end
    local env = {}
    local func = loadfile(filename);
    local envmeta = {
        __index = _G -- changed thanks to comments
    }
    setmetatable(env, envmeta) -- Allow the imported script to read only our globals
    setfenv(func, env) -- set func's _G to env
    func() -- Load the script
    return loadedmodules[filename] = env -- Set the result and return it.
end

这将是C ++等效的自动标头保护和宏自动作用于定义文件。

从Lua定义此脚本后,您可以从C ++加载它并相对简单地调用它。我不建议从C ++做任何广泛的Lua逻辑,基于堆栈的API非常可怕。