在我的项目中,我正在执行 XML 文件中包含的一些 lua 函数。我从 C++ 读取 XML,解析代码字符串,执行它们并获得结果。我发现的所有相关问题要么使用专用.lua
文件,要么直接在 Lua 中完成,但我找不到适合我的情况的解决方案。
我无法修改文件中的函数,它们都具有以下签名:
function() --or function ()
--do stuff
return 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)){
return 1;
}
argNum = load_arg_number();
if (lua_pcall(L, argNum, 1, 0)){
return 1;
}
return 0;
一切正常,但从 XML 字符串运行任意 Lua 代码似乎不太安全,所以我想设置代码可以使用的函数白名单。
在这个lua-users 讨论之后,我创建了允许的函数列表,例如:
// Of course my list is bigger
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_loadstring
lua_pcall
像这样:
.
.
size_t n = code.find("()") + 2;
code.insert(n, whitelist);
std::string wrapped_code = "return " + code;
.
.
这有效并为该函数设置了我的自定义 _ENV,但在我看来,这是一种非常老套的方法。
如何以更好的方式为从 C 加载的字符串函数设置 _ENV 变量?
如果有一种方法可以为整个保存一次lua_State
而不是每次调用函数时都可以加分。