安全なバックチック。Proc::SafePipe
Perlでバックチック(`)でくくられた文字列は、コマンドとして実行し、標準出力を値として返す。
$ret = `ls`;
とすることで、lsコマンドの結果を得られる。けど、CGI等で、ユーザの入力を
$ret = `ls $query`;
などとするのは危険。そこで、system関数、
system("ls",$query);
のように、安全に実行できるものが欲しい。
CPANで探すと、Proc::SafePipeなるものを発見。
これを使うと、
@lines = backtick_noshell $cmd, @arg;
と書ける。おそらく安全。
モジュールの中身は、ここらへんのドキュメントにある
$pid = open(KID_TO_READ, "-|"); if ($pid) { # parent while (<KID_TO_READ>) { # do something interesting } close(KID_TO_READ) || warn "kid exited $?"; } else { # child ($EUID, $EGID) = ($UID, $GID); # suid only exec($program, @options, @args) || die "can't exec program: $!"; # NOTREACHED }
を、実装した物。
openを使って、標準出力を読みとれるようにforkして、子プロセスでexecを実行するという仕組み。
ただし、Perl5.8だと、
open KID_PS, "-|", "ps", "aux" or die $!;
これで行ける。ずいぶん簡単。
ところで、バックチックのことを、手物との本にはバッククォートとも書いてあるのだが、どちらでもいいのだろうか。。