# 17.1 `rexec` -- 制限実行のフレームワーク

バージョン2.3 以降で変更された 仕様: Disabled module

警告: このドキュメントは、`rexec`モジュールを使用している古い コードを読む際の参照用として残されています。

このモジュールには `RExec` クラスが含まれています。このクラスは、 `r_eval()`、 `r_execfile()`、 `r_exec()`および `r_import()` メソッドをサポートし、これらは標準の Python 関数 `eval()`、 `execfile()` および `exec` と `import` 文の制限されたバージョンです。 この制限された環境で実行されるコードは、安全であると見なされた モジュールや関数だけにアクセスします；`RExec` をサブクラス化すれば、 望むように能力を追加および削除できます。

警告: `rexec` モジュールは、下記のように動作するべく設計されては いますが、注意深く書かれたコードなら利用できてしまうかもしれない、 既知の脆弱性がいくつかあります。従って、``製品レベル'' のセキュリティ を要する状況では、`rexec` の動作をあてにするべきではありません。 製品レベルのセキュリティを求めるなら、サブプロセスを介した実行や、 あるいは処理するコードとデータの両方に対する非常に注意深い ``浄化'' が必要でしょう。上記の代わりに、`rexec` の既知の 脆弱性に対するパッチ当ての手伝いも歓迎します。

注意: `RExec` クラスは、プログラムコードによる ディスクファイルの読み書きや TCP/IP ソケットの利用といった、 安全でない操作の実行を防ぐことができます。しかし、 プログラムコードよる非常に大量のメモリや処理時間の消費に対して 防御することはできません。

class `RExec`( | [hooks[, verbose]])

  `RExec` クラスのインスタンスを返します。

  hooks は、`RHooks` クラスあるいはそのサブクラスの インスタンスです。hooks が省略されているか `None` であれば、 デフォルトの `RHooks` クラスがインスタンス化されます。 `rexec` モジュールが (組み込みモジュールを含む) あるモジュールを 探したり、あるモジュールのコードを読んだりする時は常に、 `rexec` がじかにファイルシステムに出て行くことはありません。 その代わり、あらかじめ `RHooks` クラスに渡しておいたり、 コンストラクタで生成された `RHooks` インスタンスのメソッドを 呼び出します。

  (実際には、`RExec` オブジェクトはこれらを呼び出しません -- 呼び出しは、`RExec` オブジェクトの一部であるモジュールローダ オブジェクトによって行われます。 これによって別のレベルの柔軟性が実現されます。この柔軟性は、制限された 環境内で`import` 機構を変更する時に役に立ちます。 )

  代替の `RHooks` オブジェクトを提供することで、モジュールを インポートする際に行われるファイルシステムへのアクセスを制御する ことができます。このとき、各々のアクセスが行われる順番を制御する 実際のアルゴリズムは変更されません。 例えば、`RHooks` オブジェクトを置き換えて、ILU のような ある種の RPC メカニズムを介することで、全てのファイルシステムの要求を どこかにあるファイルサーバに渡すことができます。 Grail のアプレットローダは、アプレットを URL からディレクトリ上に import する際にこの機構を使っています。

  もし verboseが true であれば、追加のデバッグ出力が標準出力に 送られます。

制限された環境で実行するコードも、やはり `sys.exit()` 関数を 呼ぶことができることを知っておくことは大事なことです。制限された コードがインタプリタから抜けだすことを許さないためには、いつでも、 制限されたコードが、`SystemExit` 例外をキャッチする `try`/`except` 文とともに実行するように、呼び出しを防御します。 制限された環境から `sys.exit()`関数を除去するだけでは不十分です - 制限されたコードは、やはり `raise SystemExit` を使うことができてしまいます。 `SystemExit`を取り除くことも、合理的なオプションではありません； いくつかのライブラリコードはこれを使っていますし、これが利用できなくなると 中断してしまうでしょう。

参考資料:

Grail のホームページ
  Grail は すべて Python で書かれた Web ブラウザです。これは、 `rexec`モジュールを、Python アプレットをサポートするのに 使っていて、このモジュールの使用例として使うことが できます。