« sending pkt_too_big | メイン | Googleにつながらないと仕事にならない。 »

安全なバックチック。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 $!;

これで行ける。ずいぶん簡単。

ところで、バックチックのことを、手物との本にはバッククォートとも書いてあるのだが、どちらでもいいのだろうか。。