当前位置 : 主页 > 网络编程 > lua >

如何在不编辑Lua头文件或脚本的情况下从os库中删除特定函数

来源:互联网 收集:自由互联 发布时间:2021-06-23
我完成了我的作业并研究了关于这个主题的其他回复,但没有解决我的特定问题. 我想完全删除io库和os只是部分(让我们说我想保留os.clock()和其他) 我怎样才能从C API中实现这一点. 由于项
我完成了我的作业并研究了关于这个主题的其他回复,但没有解决我的特定问题.

我想完全删除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);
网友评论