CGI.pmに起因するHTMLの文字化け

CGIで掲示板を作ってみた。
http://www.sugyan.dynalias.com/~sugi/cgi-bin/cheapbbs.cgi
どうも送信後にフォームの文字が化ける。おかしいなぁ。
・・・と思ってググってみると、やっぱり情報があった!!
CGI.pm の textfield(), popup_menu(), checkbox_group() などを使ったときに HTML が文字化けするときの対処方法 - 刺身☆ブーメランのはてなダイアリー

これは、 CGI::escapeHTML() のエスケープ処理が原因 (textfield() などは内部で escapeHTML() を呼んでいるため、影響を受ける)。
いろいろなパターンを検証したわけではないが、

のときに、文字化けがおこった。

これを回避するためには、

  • CGI::autoEscape(0) とする
  • CGI::charset("utf-8") とする

いずれかをやってから textfield() などを呼ぶと、文字化けしなくなる。

<中略>

escapeHTML() を読むと、文字コードが "ISO-8859-1" か "WINDOWS-1252" だった場合に、 "\x8b" と "\x9b" という二文字をエスケープしてそれぞれ "‹" と "›" にしている。コメントによると、 "# Handle bug in some browsers with Latin charsets" だそうで、ブラウザのバグに対処するためのコードらしい。

なるほどー。CGI::charset("utf-8")がセットされていなかったから化けたのか!
前にサンプルを作ったときには入れておいたような気がするんだけど、新しく作るときにわすれてしまっていたようだ。
というわけで、

my $cgi = CGI->new;

の後に、

$cgi->charset("utf-8");

を追加してみた。解決!!