我在一个C / C ++应用程序中嵌入了Lua(5.1)。
我正在使用LuaL_openlibs()
函数来加载基础库。但是,此函数会加载一些我想要禁用的其他库,以便它们不能用于我的Lua脚本。
具体来说,我想禁用IO和OS模块。是否有一个函数可以调用程序来禁用(或卸载)这些模块,以便我可以创建一个安全的沙箱环境来运行Lua脚本?
答案 0 :(得分:13)
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);
}
}
答案 1 :(得分:9)
最简单的解决方案:加载库后只需io=nil;os=nil
。
答案 2 :(得分:8)
我不知道如何禁用模块,但您仍然可以选择加载哪些模块而不是使用luaL_openlibs
加载它们。 Section 7.3 of the Lua 5.1 manual说:
luaopen_*
函数(打开库)不能像常规C函数那样直接调用。必须通过Lua调用它们,就像Lua函数一样。
也就是说,而不是直接调用Lua 5.0中的函数:
luaopen_table(L);
...你把它作为一个带有名字的C函数推送,并在Lua 5.1中使用lua_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
答案 3 :(得分:0)
在旧版本的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 _ *()函数调用。但是,为了向后兼容,可能仍会包含旧功能。 http://www.lua.org/pil/24.1.html
HTH
答案 4 :(得分:0)
也在这里重复我的answer to another question。
从Lua 5.3开始,您需要根据luaL_openlibs中的源代码来luaL_requiref
。我发现在任何手册中都没有提到它。因此,这是一个仅打开基本库的示例,该库允许lua print
到标准输出。
#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;
}
例如,除了base
这样的I / O库之外,您还只能加载。
luaL_requiref( lua, LUA_IOLIBNAME, luaopen_io, 1 );
lua_pop( lua, 1 );
另请参阅the manual。