Perl5.8.0付属EncodeとCGI
以下の条件の場合、
use struct;
use warnings;
use utf8;
binmode STDOUT => ":encoding(shiftjis)";
binmode STDIN => ":encoding(shiftjis)";
CGIモジュールから渡されるパラメータはなぜかutf8として扱われます。
use CGI;
my $query = CGI->new();
my $value = $query->param("hoge");
# $value の値が\xff\x00\xccだとすると
# \x{00ff}\x{0000}\x{00cc}となる
この文字列をPerl5.8.0付属Encodeに渡すと正しくとエンコードされません。
困ったことに、この現象はperl5.8.8などに付属しているEncodeでは発生しません。
use Encode;
my $string = Encode::decode("shiftjis", $value);
# 目的の$stringが得られない
しょうがないのでutf8だと誤解されている$valueをただのbyte列に変更して解決しました。
use Encode;
$value = pack("C*",unpack("U*",$value));
my $string = Encode::decode("shiftjis", $value);
# 目的の$stringが得られる
pack、unpackを使えばいいことに気づくまで3時間くらいかかったよ。。。orz