如何在不编辑Lua头文件或脚本的情况下从os库中删除特定函数
2012-4-12 10:37:33
收藏:0
阅读:101
评论:2
我已经完成了我的作业,并研究了其他关于这个主题的答案,但没有一个解决了我的特定问题。
我想完全删除 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);(基本上是手动加载除os和io之外的每个库)
而不是
luaL_openlibs(L);(这会加载所有库)
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 也像往常一样工作。
原文链接 https://stackoverflow.com/questions/10108933
点赞
stackoverflow用户596285
我建议使用沙箱。请参见"如何创建安全的Lua沙箱"。
对于require
,请制作自己的包装器,在调用真实版本之前验证参数,并仅将包装器包含在沙箱中。
2012-04-11 17:37:01
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
不会有太大的帮助,因为在脚本中,用户可以调用
os = require('os')
并获取所有函数返回值。不,不会的。调用
require(os)
将简单地返回os
表。你将有所更改的同一个表。所以没有问题。所以只需在注册表后修改表。它会起作用,测试它非常容易。
注意:
luaopen _ *
不是常规的 C 函数。它们是 Lua C 函数; 它们是希望通过标准 Lua 机制调用的函数。你不能直接从 C 中调用它们。在 Lua 5.1 中,你必须将它们推到堆栈上并使用
lua_pcall
或类似的调用函数来调用它们。在 Lua 5.2 中,你应该使用luaL_requiref
,它会将它们的表放入 Luarequire
注册表中。你的代码有两个问题。首先:
lua_setglobal(LuaInstance, "io"); lua_pushnil(LuaInstance);
这并不实际更改表。它只是删除表的引用。如果要更改表本身,则必须更改表。获取
io
表并修改它。遍历表并将其中每个值设置为nil
。仅替换名为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);