Lua 5.2中的沙箱 [英] Sandboxing in Lua 5.2

查看:188
本文介绍了Lua 5.2中的沙箱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Roberto Ierusalimschy的在Lua中编程"中学习,我发现在书中,沙箱示例使用功能setfenv()来更改给定功能的环境,但是在lua 5.2中,此功能是不再可用.

I am learning from "Programing in Lua" by Roberto Ierusalimschy, and I found that in the book, the example of Sandboxing uses the function setfenv() to change the environment of a given function, but in lua 5.2 this function is no longer available.

我试图将文件(配置文件)中的某些值加载到表中的字段中,但是在lua 5.2中,我不能使用setfenv(因此我可以在给定的环境中加载值).在阅读了有关lua 5.2的一些文章后,我发现每个函数可能具有(或不具有)一个称为_ENV的上值作为环境,因此,我尝试了以下代码:

I tried to load some values from a file (a configuration file) into a field in a table, but, in lua 5.2 I can't use setfenv ( so I can load the values in the given environment). After reading some articles about lua 5.2 I found that each function may have (or not) an upvalue called _ENV which serves as the environment, so, I tried the following code:

function sandbox(sb_func, sb_env)
    if not sb_func then return nil, "sandbox function not valid" end
    sb_orig_env = _ENV
    _ENV = sb_env -- yes, replaces the global _ENV
    pcall_res, message = pcall( sb_func )
    local modified_env = _ENV -- gets the environment that was used in the pcall( sb_func )
    _ENV = sb_orig_env
    return true, modified_env
end

function readFile(filename)
    code = loadfile(filename)
    res, table = sandbox(code, {})
    if res then
        --[[ Use table (modified_env) ]]--
    else
        print("Code not valid")
end

在'sandbox'函数中替换_ENV效果很好(无法访问常规字段),但是,当执行'code'时,它似乎忽略了我替换的_ENV,它仍然可以访问常规字段(打印,加载文件,文件等).

Replacing _ENV in the 'sandbox' function works well (can't access the regular fields), but, when the 'code' is executed it seems that it ignores that I replaced _ENV, it still can access regular fields (print, loadfile, dofile, etc).

多读一点,我发现lua 5.2为此提供了一个功能,该功能是loadin(env, chunk),它在给定的环境中运行给定的块,但是,当我尝试将此功能添加到我的代码中时,该功能不存在(全局_G字段中不存在).

Reading a little more, I found that lua 5.2 provides a function for this purpose, this function is loadin(env, chunk), which runs the given chunk in the given environment, but, when I try to add this function to my code, the function doesn't exist ( Is not present in the global _G field).

一些帮助将不胜感激.

推荐答案

sandbox内部分配给_ENV时,您不会覆盖全局环境,而是替换当前正在运行的代码的_ENV升值.将呼叫添加到print(_ENV)可能有助于您更好地了解所涉及表的身份.

When you assign to _ENV from within sandbox, you're not overwriting the global environment--you're replacing the _ENV upvalue of the currently running code. Adding calls to print(_ENV) may help you better understand the identities of the tables involved.

例如:

function print_env()
  print(_ENV)
end

function sandbox()
  print(_ENV) -- prints: "table: 0x100100610"
  -- need to keep access to a few globals:
  _ENV = { print = print, print_env = print_env, debug = debug, load = load }
  print(_ENV) -- prints: "table: 0x100105140"
  print_env() -- prints: "table: 0x100105140"
  local code1 = load('print(_ENV)')
  code1()     -- prints: "table: 0x100100610"
  debug.setupvalue(code1, 1, _ENV) -- set our modified env
  code1()     -- prints: "table: 0x100105140"
  local code2 = load('print(_ENV)', nil, nil, _ENV) -- pass 'env' arg
  code2()     -- prints: "table: 0x100105140"
end

loadin函数存在于Lua 5.2的某些预发行版本中,但在最终发行版本之前已被删除.相反,Lua 5.2 loadloadfile函数接受env参数.您还可以使用 debug.setupvalue修改另一个函数的_ENV .

The loadin function was present in some pre-release versions of Lua 5.2 but was removed before the final release. Instead, the Lua 5.2 load and loadfile functions take an env argument. You can also modify the _ENV of another function using debug.setupvalue.

这篇关于Lua 5.2中的沙箱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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