我想完全删除io库和os只是部分(让我们说我想保留os.clock()和其他)
我怎样才能从C API中实现这一点.
由于项目的性质,我不允许修改Lua标头和将发送给我的脚本.这些不在我的控制之下.我唯一可以修改的是解释器.
做这样的事情:
lua_pushnil(state_pointer); lua_setglobal(state_pointer, "os.execute");
没有多大帮助,因为在脚本中用户可以调用os = require(‘os’)并获取所有功能
我不允许禁用require函数,因此这会使事情变得更难.
有任何想法吗?
PS:更多的好奇心:如果我做了类似的事情
luaopen_base(L); luaopen_table(L); luaopen_string(L); luaopen_math(L); luaopen_loadlib(L); (basically i'm loading every library by hand except os and io)
代替
luaL_openlibs(L); (this loads all the libraries)
os = require(‘os’)或io = require(‘io’)仍然有效吗?
@Nicol Bolas不知道我做错了什么但os = require(‘os’)& require(‘io’)只是把一切都带回来.
我的代码:
luaL_openlibs(LuaInstance); /* load the libs */ lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "io"); lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "os.execute"); lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "os.rename"); lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "os.remove"); lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "os.exit");
在我的脚本中,我只是做了一个
os = require('os') io = require('io')
在此os函数和io函数之后所有工作. os.exit仍然关闭我的应用程序,io.write像往常一样工作
won’t help much because in the script the user can call os = require(‘os’) and get all the functions back
不,它不会.调用require(os)将只返回os表.您将修改的同一个表.所以没有问题.
所以只需在注册后修改表格.它会工作,测试它确实很容易.
luaopen_base(L);
请注意:luaopen_ *不是常规的C函数.它们是Lua C函数;它们是期望通过标准Lua机制调用的函数.你不能直接从C打电话给他们.
在Lua 5.1中,你必须在堆栈上使用它们并使用lua_pcall或类似的调用函数来调用它们.在Lua 5.2中,你应该使用luaL_requiref,它将把他们的表放入Lua require注册表中.
您的代码有两个问题.第一:
lua_setglobal(LuaInstance, "io"); lua_pushnil(LuaInstance);
这实际上并没有改变表格.它只是删除对表的引用.如果要更改表本身,则必须更改表.你必须得到io表并进行修改.走桌子并将其中的每个值设置为零.简单地替换名为io的全局变量的内容将不起作用.
但是,如果要防止io被完全使用,则不应将其注册为开头.
第二个问题是:
lua_pushnil(LuaInstance); lua_setglobal(LuaInstance, "os.execute");
这会修改全局表的值,该键的键是[“os.execute”].它相当于这个Lua代码:
_G["os.execute"] = nil
这与以下内容不同:
os.execute = nil;
当你在Lua中使用os.execute时,这意味着获取全局表(_G),使用名为“os”的键找到值,并在从“os”获取的表中找到“execute”键.
当您执行_G [“os.execute”]时,您所说的是获取全局表并使用名为“os.execute”的键查找值.
看到不同?
你想要做的是获取存储在全局变量os中的表并修改该表.你不能使用lua_setglobal,因为os表的成员不是全局的;他们是桌子的成员.是的,它们存储的表恰好是全局的.但是您无法使用lua_setglobal修改存储在全局中的表的成员.
你必须这样做:
lua_getglobal(L, "os"); lua_pushnil(L); lua_setfield(L, -2, "execute"); lua_pushnil(L); lua_setfield(L, -2, "rename"); lua_pushnil(L); lua_setfield(L, -2, "remove"); lua_pushnil(L); lua_setfield(L, -2, "exit"); lua_pop(L, 1);