0Pricing
Lua Academy · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Lua 5.2以降の_ENVモデル
  2. 制限付きサンドボックスの構築
  3. サンドボックス脱出の防止
  4. リソース制限とインストルメンテーション
← Lua Academyに戻る