如何在Lua中将表格设为只读? (具体来说,LuaInterface与Lua 5.1 for C#,但我认为这不会改变任何东西)
我知道如何使用__index
和__newindex
,但这并不妨碍某人运行:
math = nil
,可能导致进一步的脚本错误执行。
我目前的“保护”功能:
function protect(table)
return setmetatable({}, { __index = table,
__newindex = function(table, key, value) error("attempted to modify a read only table")
end, __metatable = false }) end
math = protect(math)
math.sqrt = nil // successfully protected
math = nil // this is bad and can happen!
答案 0 :(得分:5)
全球环境只是一张桌子。在Lua 5.1中,每个函数(编译的Lua脚本都是这样)都有自己的环境,您可以更改。如果您想要沙箱脚本以便它们无法修改全局表,您可以通过用沙盒替换其环境来实现。
基本上,您创建一个只读表,将您希望它们能够访问的内容放入其中。您甚至可以设置metatable以防止覆盖现有元素,但允许它们修改当前不存在的条目(即:它们可以创建并使用它们自己的全局变量)。
话虽如此,除非您将用户移除rawget
/ rawset
的能力,否则他们可以随时支持您的沙箱并开始破坏这些表格。
更安全的版本是通过复制函数为每个脚本构建一个环境。而不是每个脚本都获得相同的math
表,而是获得原始文件的副本,这些副本在脚本无法触及的地方被捕获。