私はRoberto Ierusalimschyの "Programing in Lua"から学んでいますが、本書ではSandboxingの例では、関数setfenv()
を使用して特定の関数の環境を変更していますが、機能はもはや利用できません。Luaのサンドボックス化5.2
ファイル(構成ファイル)からテーブルのフィールドに値をロードしようとしましたが、ルア5.2ではsetfenvを使用できません(指定された環境で値をロードできます)。 「サンドボックス」で
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
_ENV
を交換:LUA 5.2についてのいくつかの記事を読んだ後、私は、次のコードを試み、各関数は環境として機能_ENVと呼ばれる上位値を有する(またはしない)ことが見出され、これ(通常のフィールドにはアクセスできませんが) 'code'が実行されると、_ENV
を置き換えても無視されるようですが、通常のフィールド(print、loadfile、dofileなど)にはまだアクセスできます。
もう少し読んで、私はこの目的のための関数を提供することを発見しました。この関数はloadin(env, chunk)
です。与えられた環境で与えられたチャンクを実行しますが、この関数を自分のコードに追加しようとすると、関数が存在しません(グローバル_G
フィールドには存在しません)。
何か助けていただければ幸いです。現在実行中のコードの_ENV
上位値を置き換えるyou're - あなたは内から_ENV
に割り当てるとき
ありがとうございます!解決は簡単でした。 'setfenv'がロードされたコードで使われていたので、' load'と 'loadfile'で環境を変更するこのアプローチがより良いと思います...ありがとう!私は期待どおりにサンドボックス化しました。 –
@Miles print_env()が定義されているときに、グローバル_ENVを上位値として受け取っていませんか? print_env()がsandbox()の内側で呼び出されたとき、どのように変更されましたか? –
@TiagoCosta upvaluesは外部ローカル変数です。この場合の '_ENV'はチャンクに対してローカルです。 '_ENV'への代入はチャンクローカル変数に影響します。これは両方のクロージャの共有されたupvalueです。 – Miles