C++ LuaL_openlibs()和沙箱脚本
我正在C/C++应用程序中嵌入Lua(5.1) 我正在使用C++ LuaL_openlibs()和沙箱脚本,c++,c,lua,C++,C,Lua,我正在C/C++应用程序中嵌入Lua(5.1) 我正在使用LuaL\u openlibs()函数加载基本libs。但是,此函数会加载一些我想要禁用的其他库,以便我的Lua脚本无法使用这些库 具体来说,我想禁用IO和OS模块。是否有一个函数可以调用以编程方式禁用(或卸载)这些模块,以便创建一个安全的沙箱环境来运行Lua脚本?在旧版本的Lua中,您可以指定要加载的库。具体而言,在我的lualib.h副本中,我看到声明了以下函数: LUALIB_API int (luaopen_base) (lua_
LuaL\u openlibs()
函数加载基本libs。但是,此函数会加载一些我想要禁用的其他库,以便我的Lua脚本无法使用这些库
具体来说,我想禁用IO和OS模块。是否有一个函数可以调用以编程方式禁用(或卸载)这些模块,以便创建一个安全的沙箱环境来运行Lua脚本?在旧版本的Lua中,您可以指定要加载的库。具体而言,在我的lualib.h副本中,我看到声明了以下函数:
LUALIB_API int (luaopen_base) (lua_State *L);
LUALIB_API int (luaopen_table) (lua_State *L);
LUALIB_API int (luaopen_io) (lua_State *L);
LUALIB_API int (luaopen_os) (lua_State *L);
LUALIB_API int (luaopen_string) (lua_State *L);
LUALIB_API int (luaopen_math) (lua_State *L);
LUALIB_API int (luaopen_debug) (lua_State *L);
LUALIB_API int (luaopen_package) (lua_State *L);
LUALIB_API void (luaL_openlibs) (lua_State *L);
我无法告诉您不加载所有库的后果,因为我在代码中调用了luaL_openlibs()。Lua编程的第一版可以在线获得,其中提到luaL_openlibs()应该取代luaopen_*()函数调用。但是,为了向后兼容,可能仍会包括旧函数
HTH我不知道如何禁用模块,但您仍然可以选择加载哪些模块,而不是使用
luaL\u openlibs
加载所有模块。说:
与常规C函数一样,无法直接调用luaopen.*
函数(用于打开库)。它们必须通过Lua调用,就像Lua函数一样
也就是说,与Lua 5.0中直接调用函数不同:
luaopen_table(L);
。。。您可以将其作为一个名为的C函数推送,并在LUA5.1中使用lua\u call
或类似功能:
lua_pushcfunction(L, luaopen_table);
lua_pushliteral(L, LUA_TABLIBNAME);
lua_call(L, 1, 0);
您可以使用的功能在lualib.h
中列出:
Function | Name
----------------+-----------------
luaopen_base | ""
luaopen_table | LUA_TABLIBNAME
luaopen_io | LUA_IOLIBNAME
luaopen_os | LUA_OSLIBNAME
luaopen_string | LUA_STRLIBNAME
luaopen_math | LUA_MATHLIBNAME
luaopen_debug | LUA_DBLIBNAME
luaopen_package | LUA_LOADLIBNAME
luaL_openlibs
只是在同一文件中声明的库加载器列表中进行迭代。只需删除/注释掉luaopen_io
和luaopen_os
行即可。完成了
如果您不赞成编辑Lua源代码,那么您可以定义自己的函数,而不使用这两个库:
#define LUA_LIB
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};
LUALIB_API void my_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
}
最简单的解决方案是:只需执行
io=nil;加载库后os=nil
。也在此处重复我的操作
从Lua 5.3开始,您需要基于中的源代码luaL_requiref
这些。我在任何手册中都没有找到这方面的参考资料。下面是一个只打开基本库的示例,它允许lua将打印为标准输出
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int main( int argc, char *argv[] ) {
lua_State *lua = luaL_newstate();
luaL_requiref( lua, "_G", luaopen_base, 1 );
lua_pop( lua, 1 );
luaL_dostring( lua, "print \"Hello, lua\"" );
lua_close( lua );
return 0;
}
另请参见。谢谢你的回答(我太喜欢这个选择了)。我会对这个答案投+1票(不幸的是,我不能投票!)。我不得不选择董建华的答案,因为他首先回答了类似的信息。但是我很感激这两个答案。我应该注意到这是针对Lua5.1的,虽然它可能适用于Lua5.2,但它不再是推荐的方式。最好的办法是查看lua发行版的linit.c文件,看看它们是如何做到的。这还不够,用户可以要求它们返回
io=require('io')
luaL_requiref( lua, LUA_IOLIBNAME, luaopen_io, 1 );
lua_pop( lua, 1 );