如何在不编辑Lua头文件或脚本的情况下从os库中删除特定功能 [英] How to remove particular functions from os library without editing the Lua headers or the scripts

查看:65
本文介绍了如何在不编辑Lua头文件或脚本的情况下从os库中删除特定功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经完成作业并研究了有关此主题的其他答案,但没有一个解决我的特定问题.

I have done my homework and studied other responses on this topic but none address my particular issue.

我想完全删除io库,而仅部分删除os(比方说,我想保留os.clock()等)

I want to remove the io library completely and the os only partially (let's say i want to keep os.clock() and others)

我怎么只能从C API做到这一点.

How can I achieve this only from the C API.

由于项目的性质,不允许我修改Lua标头和将发送给我的脚本.这些不在我的控制之下.我唯一可以修改的是解释器.

Due to the nature of the project I am not allowed to modify the Lua headers and the scripts that will be sent to me. These are not under my control. The only thing I can modify is the interpreter.

做这样的事情:

lua_pushnil(state_pointer);
lua_setglobal(state_pointer, "os.execute");

不会有太大帮助,因为用户可以在脚本中调用os = require('os')并取回所有功能

won't help much because in the script the user can call os = require('os') and get all the functions back

不允许我禁用require函数,这样会使事情变得更困难.

I am not allowed to disable the require function so this makes things harder.

有什么想法吗?

PS:更多的是好奇:如果我做类似的事情

PS:More of a curiosity: if I do something like

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')仍然可以使用吗?

would os = require('os') or io = require('io') still work?

@Nicol Bolas不知道我做错了什么,但是os = require('os')& require('io')只是带回了一切.

@Nicol Bolas don't know if i'm doing something wrong but os = require('os') & require('io') just brings everything back.

我的代码:

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");

在我的脚本中,我只是做一个

In my script i just do a

os = require('os')
io = require('io')

此后,os函数和io函数全部起作用. os.exit仍然关闭我的应用程序,io.write照常工作

after this os functions and io functions all work. os.exit still closes my app and io.write works as usual

推荐答案

不会有太大帮助,因为用户可以在脚本中调用os = require('os')并取回所有功能

won't help much because in the script the user can call os = require('os') and get all the functions back

不,不会.调用require(os)将仅返回os表.您将修改的同一张表.因此没有问题.

No, it won't. Calling require(os) will simply return the os table. The same table you will have modified. So there's no problem.

因此,只需在注册后修改表即可.它会起作用,并且测试它确实很容易.

So just modify the table after you register it. It will work, and it's really easy to test that it does.

luaopen_base(L);

luaopen_base(L);

请注意:luaopen_*不是常规的C函数.它们是 Lua C函数;它们是希望通过标准Lua机制调用的函数.您不能直接从C调用它们.

Be advised: luaopen_* are not regular C functions. They are Lua C functions; they're functions that expect to be called via the standard Lua mechanisms. You can't call them directly from C.

在Lua 5.1中,必须使用将它们压入堆栈并使用lua_pcall或类似的调用函数来调用它们.在Lua 5.2中,您应该使用luaL_requiref,它将其表放入Lua require注册表中.

In Lua 5.1, you must use push them on the stack and use lua_pcall or similar calling functions to call them. In Lua 5.2, you should use luaL_requiref, which will put their tables into the Lua require registry.

您的代码有两个问题.首先:

Your code has two problems. First:

lua_setglobal(LuaInstance, "io");
lua_pushnil(LuaInstance);

这实际上并没有更改表.它只是将 reference 删除到表中.如果要更改表本身,则必须更改表.您必须获取io表并对其进行修改.遍历表格并将其中的每个值设置为nil.仅仅替换名为io的全局变量的内容将无济于事.

This does not actually change the table. It simply removes the reference to the table. If you want to change the table itself, then you must change the table. You have to get the io table and modify it. Walk the table and set each value in it to nil. Simply replacing the contents of the global variable called io will do nothing.

但是,如果要防止完全使用io,则不应该先注册它.

However, if you want to prevent io from being used entirely, you shouldn't register it to begin with.

第二个问题是:

lua_pushnil(LuaInstance);
lua_setglobal(LuaInstance, "os.execute");

这将修改键为["os.execute"]的全局表的值.等效于以下Lua代码:

This modifies the value of the global table who's key is ["os.execute"]. It is the equivalent of this Lua code:

_G["os.execute"] = nil

这与相同:

os.execute = nil;

在Lua中使用os.execute时,这意味着要获取全局表(_G),使用名为"os"的键查找值,并在从"os"获取的表中找到"execute"

When you use os.execute in Lua, that means to take the global table (_G), find the value with the key named "os" and find the "execute" key within the table fetched from "os".

当您执行_G["os.execute"]时,您要说的是获取全局表并使用名为"os.execute"的键查找值.

When you do _G["os.execute"], what you're saying is to take the global table and find the value with the key named "os.execute".

看到区别了吗?

您要做的是获取存储在全局变量os中的表,并修改 that 表.您不能使用lua_setglobal,因为os表的成员是 not 全局变量.他们是表的成员.是的,存储它们的表恰好是全局的.但是您不能使用lua_setglobal修改存储在全局变量中的表的成员.

What you want to do is get the table stored in the global variable os and modify that table. You can't use lua_setglobal, because the members of the os table are not globals; they're members of a table. Yes, the table that they are stored in just so happens to be a global. But you can't modify the members of a table stored in a global with 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);

这篇关于如何在不编辑Lua头文件或脚本的情况下从os库中删除特定功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆