15 May 2011

(Perl) ファイルアップロードで"Wide character in print ..." 警告が出る

CGI.pmのupload関数を用いた、一般的なアップロード処理で、Wide character in print at (eval 19) line 94., referer: http://example.com/index.cgiのような警告がApache2のerror.logに大量に出力される。

■ 原因

CGIクラスを初期化するmy $q = new CGI;コーディングの前に、STDINをバイナリ以外に設定してしまっている。

今回は、binmode(STDIN, ":utf8");と設定していたのがミス。

■ 問題あるコーディング


use warnings;
use strict;
use utf8;
use CGI;
use File::Copy;

binmode(STDIN, ":utf8"); ← この行がエラーの原因
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");

my $q = new CGI;
my $filename = param('uploadfile');
my $fh = $q->upload('uploadfile');
my $tempfile = tmpFileName($fh);
File::Copy::move($tempfile, $filename);
close($fh);

スクリプトの共通部分を使いまわしているため、入出力のエンコードを一括して設定している部分が悪さをしていたわけだ。

■ 問題を修正


use warnings;
use strict;
use utf8;
use CGI;
use File::Copy;

binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");

my $q = new CGI;
my $filename = param('uploadfile');
my $fh = $q->upload('uploadfile');
my $tempfile = tmpFileName($fh);
File::Copy::move($tempfile, $filename);
close($fh);

■ 参考資料
CGI.pm: "Malformed UTF-8 character" in apache's error.log