从 C++ 为字符串函数设置 ENV

在我的项目中,我执行一些包含在 XML 文件中的 Lua 函数。我从 C++ 中读取 XML,解析代码字符串,执行它们并获取结果。 我找到的所有相关问题都使用了专用的'.lua'文件,或在 Lua 直接执行,我找不到适用于我的情况的解决方案。

我无法修改文件中的函数,并且它们都具有以下签名:

function() -- 或 function ()
    -- 做一些事情
    返回 foo
end

我通过 C++ 加载它们,如下所示:

lua_State *L = luaL_newstate();
luaL_openlibs(L);
std::string code = get_code_from_XML();
std::string wrapped_code = "return " + code;
luaL_loadstring(L, wrapped_code.c_str());
if (lua_pcall(L, 0, 1, 0)){
    返回 1;
}

argNum = load_arg_number();

if (lua_pcall(L, argNum, 1, 0)){
    返回 1;
}
返回 0;

一切都正常工作,但从 XML 字符串中运行任意 Lua 代码似乎并不是很安全,所以我想设置一个代码可以使用的函数白名单。

根据 lua-users 讨论,我创建了我的允许函数列表,如下所示:

// 当然我列表更长
std::string whitelist = "sandbox_env = {ipairs = ipairs} _ENV = sandbox_env"

问题在于我不知道如何加载它以在我调用的函数中可用。

我尝试像 lua-users 网站上那样做:

std::string Lua_sandboxed_script_to_run( Lua_sandboxing_script + Lua_script_to_run )

if (luaL_dostring(sandboxed_L, Lua_sandboxed_script_to_run))
{
   // error checking
}

但这导致函数加载不正确并出现 Lua 错误

尝试执行字符串值

我还尝试执行:

luaL_loadstring(L, whitelist.c_str());
lua_getglobal(L, "_ENV");
lua_setupvalue(L, -2, 1);

在执行加载的 XML 函数之前,这并没有使程序崩溃,但也没有为调用的函数设置 '_ENV'。

我发现实现这一点的唯一方法是使用 C++ 解析函数字符串,搜索 (),在其后插入 whitelist,然后两次 luaL_loadstringlua_pcall 执行它。

像这样:

.
.
size_t n = code.find("()") + 2;
code.insert(n, whitelist);
std::string wrapped_code = "return " + code;
.
.

这就是我想要的,它为函数设置了我的自定义 _ENV,但对我来说,它似乎是一个真正蹩脚的方法。

有没有更好的方法为从 C++ 加载的字符串函数设置 _ENV 变量?

如果有一种可以为整个lua_State保存它的方法,并且不必每次调用函数都设置它,那就有额外的奖励分数。

点赞