さすがにこの目的のためだけにXS Hackというのは、ハエ退治にパトリオットミサイル撃つようなものなので、キンチョールも紹介しておきたく。
PL_check hack - daily dayflowerゴール#!/usr/bin/perl eval 'print "Hello ' . $ARGV[0] . '!\n"';とか危険ですよねー*1。こんな機能があるなんてけしからん。ですので,eval の実行を抑制するモジュールを書いてみました。
そのためには、Safeモジュールを使います。Perl 5.02からCOREに入っている由緒あるモジュールです。Malcolm Beattie がBのフレームワークを作った理由の一つが、これを可能にすることでした。今はpumpkingの Rafaël Garcia-Suarez がメンテしています。
で、何をするモジュールかというと、opcodeの一つ一つをオンにしたりオフにしたり出来るモジュールです。
まずはこういうファイルを用意しましょう。
#!perl
use strict;
use warnings;
use Safe;
$ARGV[0] ||= 'world'; # for codepad
my $safe = Safe->new;
# $safe->permit(qw/print entereval/);
$safe->reval(qq{
print "Hello ", $ARGV[0], "!\n";
eval 'print "Hello ", $ARGV[0], "!\n"';
});
die $@ if $@;
実行してみます。
[run via codepad]eval "string" trapped by operation mask at (eval 2) line 5.
今度は、# $safe->permit(qw/print entereval/)をuncommentして実行してみましょう。
Hello world! Hello world!
今度はうまく行きました。
それでは次に、qq{ ... }をq{ ... }にしてみましょう。
Hello ! Hello !
はまちちゃんになっちゃいました。じゃなくて、@ARGVがSafe環境と共有されていないことがわかりました。
で、具体的にevalだけ殺してみましょう。$safe->permit(qw/print entereval/)からenterevalを取り除いてみて下さい。
eval "string" trapped by operation mask at (eval 2) line 3.
evaレないことが確認できます。
それではファイルを最初のバージョンに戻して、コマンドラインからこう打ってみて下さい。codepadの禁則事項なので、各自お願いします。
% /usr/bin/perl safe.pl 'qx(date)'
こうなったはずです。
'quoted execution (``, qx)' trapped by operation mask at (eval 2) line 2.
Safeを使うと、Taint Modeでは不可能なきめ細かいコントロールが出来ます。Taint Modeが使えない、mod_perlで使うことが出来る点もぐーです。
続きは
で!
Dan the Safe Perl Monger
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。