Eval
From Wikipedia, the free encyclopedia
信頼されないソースからのデータをevalするときには特に注意が必要である。例としてインターネット上からデータを得る get_data() 関数を考える。次の擬似コードのようなプログラムは潜在的に危険である。
data = get_data() foo = eval(data)
攻撃者がこのプログラムに例えば "delete_system_files()" という文字列を与えることができると、delete_system_files() 関数が実行されてしまい、重要なファイルが消されてしまうかもしれない。これを防ぐためには、evalされる文字列はすべてエスケープしたり、潜在的に危険な機能を利用できないようにして実行するなどの対策が必要となる。プログラミング言語によっては、外部から入力されたデータを「汚染されている」として印をつけるものもある。
適切な使用
evalは非常に強力なため、経験の浅いプログラマは何でもevalを使って済ませてしまうことがある。たいてい、そのような場合には専用のより良い選択肢が存在し、コードのパースにかかる時間が節約できる。
例えば、evalは簡易テンプレートエンジンとして使われることがある。PHPでの例を示す。
$name = 'John Doe';
$greeting = 'Hello';
$template = '"$greeting, $name! How can I help you today?"';
print eval("return $template;")
この例は期待した動作をするが、前述のようにセキュリティ上の問題を抱えており、他の方法よりもはるかに遅い。より高速で安全な方法は単に "$name" という文字列を $name の値で置換することである。
eval は表計算ソフトなどの数式を評価する必要のあるアプリケーションで使われることがある。これは数式のパーサを自作するよりも手軽だが、自作や既存の専用のパーサを利用するほうがより良い。前述の問題点に加え、言語組み込みのevalはアプリケーション用にカスタマイズできないからである。
おそらく、evalの最も優れた使い道は(LISPなどでの)処理系のブートストラップや、言語の対話的な実行環境でユーザが書いたプログラムを実行することであろう。
実装
インタプリタ言語ではevalは通常のコードと同じインタプリタで実装されるのがほとんどである。
コンパイラ言語ではevalを実装するために通常のコンパイラをプログラムに埋め込むこともある。また特別のインタプリタを使うこともあり、その場合はコードの重複が問題となる。