Lua 5.2以降の_ENVモデル
_ENVがsetfenvに取って代わり、環境を制御できるようにした仕組みを理解します。
「Lua 5.2以降の_ENVモデル」はCoddyKit上の無料Lua Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLua Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Lua Academyコースには全4レッスンが含まれています。
_ENVとは
Lua 5.2以降では、すべてのチャンクに_ENVという暗黙のupvalueがあります。すべてのグローバル変数へのアクセスは、_ENVに対するフィールドアクセスに書き換えられます。つまり、print(x)は_ENV.print(_ENV.x)になります。
_ENVはsetfenvを置き換える
Lua 5.1では、setfenv(fn, env)によって関数のグローバル環境を変更していました。5.2以降では、この機能は廃止されています。代わりに、_ENVをローカル変数として設定し、チャンクまたはブロックの環境を変更します。
チャンク内での_ENVの変更
チャンクの先頭で_ENVを設定すると、すべてのグローバルアクセスの向き先を変更できます。
-- Everything in this chunk uses myEnv as globals
local _ENV = myEnv
print("hello") -- calls myEnv.print("hello")ブロック用のローカル_ENV
do...endブロック内に_ENVの変更のスコープを限定し、影響範囲を制限します。
do
local _ENV = {print = print, x = 42}
print(x) -- 42 from local _ENV
end
print(x) -- original _ENV.x (global x)_ENVとloadの使用
load(chunk, chunkname, mode, env)は、カスタム環境を使用して文字列をチャンクとして実行します。これは5.2以降における主要なサンドボックス化の仕組みです。
local env = {print = print, math = math}
local fn, err = load("print(math.sqrt(16))", "sandbox", "t", env)
if fn then fn() end -- 4.0現在の_ENVの読み取り
現在のチャンクのグローバル変数は_ENVにあります。参照を取得するには、local myEnv = _ENVとします。
実行時の_ENVの変更
グローバル変数の設定は_ENV.varName = valueで行います。_ENVはupvalueなので、コードの任意の時点で別のテーブルに置き換えられます。
__indexによる継承
サンドボックス環境に__index = _Gを持つメタテーブルを設定すると、明示的にブロックしていない関数については実際のグローバルテーブルにフォールバックできます。
local sandboxEnv = setmetatable({}, {__index = _G})
-- then block dangerous ones:
sandboxEnv.os = nil
sandboxEnv.io = nil
sandboxEnv.load = nil_ENVへのアクセス試行の検出
危険なグローバル変数を、アクセス試行を記録するセンチネルに置き換えて、セキュリティ監査に利用します。
sandboxEnv.os = setmetatable({}, {
__index = function(_, k)
ngx.log(ngx.WARN, "Blocked access: os." .. k)
return nil
end
})互換性に関する注意
Lua 5.1のsetfenvまたはgetfenvを使用するライブラリは、5.2以降向けに書き換える必要があります。初期化コードで互換性シムを使用するライブラリもあります。
実用上の効果
_ENVモデルによって、サンドボックス化がより明確で一貫したものになります。関数用のsetfenvとトップレベル用のグローバル変数という2つの仕組みではなく、環境を扱う明確な仕組みが1つになります。
_ENVに関する質問
Lua 5.2以降では、グローバルアクセスprint(x)はどのように書き換えられますか。
振り返り: _ENVモデル
Lua 5.2以降では、すべてのグローバルアクセスが_ENVのupvalueを経由します。load(code, name, "t", env)を使用すると、カスタム環境でコードを実行できます。これはsetfenvに代わる標準的なサンドボックス化の仕組みです。
よくある質問
「Lua 5.2以降の_ENVモデル」レッスンは無料ですか?
はい。「Lua 5.2以降の_ENVモデル」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Lua Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Lua Academyコースには全4レッスンが含まれています。
「Lua 5.2以降の_ENVモデル」で何を学びますか?
_ENVがsetfenvに取って代わり、環境を制御できるようにした仕組みを理解します。 ブラウザで直接実行するハンズオンコードでLua Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Lua Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのLua Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「Lua 5.2以降の_ENVモデル」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このLua Academyレッスンでコードを書いて実行できますか?
はい。すべてのLua Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- Lua 5.2以降の_ENVモデル
- 制限付きサンドボックスの構築
- サンドボックス脱出の防止
- リソース制限とインストルメンテーション