一个默认启用本地变量的程序
A program to enable local by default variables
所以我对 Lua 中的全局默认样式感到恼火。我正在尝试编写一个程序,使所有 运行 之后的程序都无法创建全局变量。当他们尝试时,该变量将被设置为该程序的函数环境。我想出了这个,它似乎有效,但由于某种原因在 ComputerCraft rom/programs/edit 中的 [edit: 9] 中抛出了一个错误。当我运行一个测试程序时,
a = 1
print(a)
它工作正常并阻止创建全局变量,同时仍然允许该程序访问它,但它不适用于其他程序。我试过做 _G.a、本地 a 和其他事情,但它们都有效。有谁知道为什么它可能不适用于其他程序?
local oldload = loadfile
function _G.loadfile(str)
local func = oldload(str)
local env = {}
env._G = env
setmetatable(env, {__index = _G, __newindex =
function(table, var, val)
rawset(env, var, val)
end})
setfenv(func, env)
return func
end
Lua 被设计成一种嵌入式语言。这意味着最终的仲裁者是宿主语言 C.
一个 Lua 脚本可以通过沙盒技术实现对另一个脚本的控制。您没有完全沙盒您的脚本。您更改了 loadfile
,但没有更改 load
或 dofile
。
但这并不重要。为什么?因为论统治力,C总是胜。看,C 不调用 Lua loadfile
函数。好吧,它显然可以,但通常不会。相反,它调用 Lua API luaL_loadfile
.
Lua代码可以为它直接加载的其他Lua代码建立一个沙箱。但是基于 Lua 的沙箱对 C 代码没有影响,除非该代码被特意设计为存在于 Lua 沙箱中。大多数 C 库都不是。
这意味着,一旦您决定在您无法控制的 C 执行环境中 运行,您的 Lua 沙箱将毫无意义。 C 代码可以并且在许多情况下将会加载您无法控制的脚本,并为它们提供它想要的任何环境。
从 Lua 开始,您无能为力。解决此问题的唯一方法是修改 Lua .dll 本身以建立您的沙箱。
我找到了解决办法。事实证明,许多 ComputerCraft 程序中使用的 shell API 不在 _G 中,因此在我应用沙箱时无法访问。这是我的新功能代码:
local oldload = load
function _G.load(str, arg1, arg2, arg3)
local func = oldload(str, arg1, arg2, arg3)
local env = getfenv(func)
if (env == _G) then
env = {}
env._G = env
end
setmetatable(env, {__index = _G, __newindex = function(table, var, val) rawset(env, var, val) end})
setfenv(func, env)
return func
end
所以我对 Lua 中的全局默认样式感到恼火。我正在尝试编写一个程序,使所有 运行 之后的程序都无法创建全局变量。当他们尝试时,该变量将被设置为该程序的函数环境。我想出了这个,它似乎有效,但由于某种原因在 ComputerCraft rom/programs/edit 中的 [edit: 9] 中抛出了一个错误。当我运行一个测试程序时,
a = 1
print(a)
它工作正常并阻止创建全局变量,同时仍然允许该程序访问它,但它不适用于其他程序。我试过做 _G.a、本地 a 和其他事情,但它们都有效。有谁知道为什么它可能不适用于其他程序?
local oldload = loadfile
function _G.loadfile(str)
local func = oldload(str)
local env = {}
env._G = env
setmetatable(env, {__index = _G, __newindex =
function(table, var, val)
rawset(env, var, val)
end})
setfenv(func, env)
return func
end
Lua 被设计成一种嵌入式语言。这意味着最终的仲裁者是宿主语言 C.
一个 Lua 脚本可以通过沙盒技术实现对另一个脚本的控制。您没有完全沙盒您的脚本。您更改了 loadfile
,但没有更改 load
或 dofile
。
但这并不重要。为什么?因为论统治力,C总是胜。看,C 不调用 Lua loadfile
函数。好吧,它显然可以,但通常不会。相反,它调用 Lua API luaL_loadfile
.
Lua代码可以为它直接加载的其他Lua代码建立一个沙箱。但是基于 Lua 的沙箱对 C 代码没有影响,除非该代码被特意设计为存在于 Lua 沙箱中。大多数 C 库都不是。
这意味着,一旦您决定在您无法控制的 C 执行环境中 运行,您的 Lua 沙箱将毫无意义。 C 代码可以并且在许多情况下将会加载您无法控制的脚本,并为它们提供它想要的任何环境。
从 Lua 开始,您无能为力。解决此问题的唯一方法是修改 Lua .dll 本身以建立您的沙箱。
我找到了解决办法。事实证明,许多 ComputerCraft 程序中使用的 shell API 不在 _G 中,因此在我应用沙箱时无法访问。这是我的新功能代码:
local oldload = load
function _G.load(str, arg1, arg2, arg3)
local func = oldload(str, arg1, arg2, arg3)
local env = getfenv(func)
if (env == _G) then
env = {}
env._G = env
end
setmetatable(env, {__index = _G, __newindex = function(table, var, val) rawset(env, var, val) end})
setfenv(func, env)
return func
end