diff -urN ../htmllint.orig/htmllint.cgi ./htmllint.cgi --- ../htmllint.orig/htmllint.cgi Fri Aug 3 23:45:36 2012 +++ ./htmllint.cgi Fri Sep 28 13:20:00 2012 @@ -75,6 +75,21 @@ my $addinfo = defined(&AddInfo); &ShortName; +# フォームの漢字コードの検出 +# 適切な値を設定したhiddenフィールドをフォーム中にあらかじめ入れておく。 +# EncodeにもEncodeHintにも有効な値が無い場合は($formCODE=undef)、 +# Jconvertが変換対象文字列からそのつど自動識別するが、 +# 対象文字列によっては必ずしも正しく検出するとは限らない。 +# EncodeHintはフォームのあるHTMLを文字コード変換した際や +#
を指定した際にもそのまま対応できるので +# 付属のhtmllint.htmlのような長期的に使用する送信フォームで利用することを、 +# Encodeはuse-htmllintcgi.htmlの解説にあるような各ユーザーが作る +# 簡易な送信フォームで利用することを意図した。 +# 変数を役割別に'Encode'と'EncodeHint'とに分けたが、どちらか一つの +# 変数で両方の役割を兼ねてもよかったかもしれない。 +my $formCODE = ($cgi->param('Encode') =~ /^(jis|euc|sjis|utf8)$/oi && lc($1) or + &Jgetcode(\$cgi->param('EncodeHint')) =~ /^(jis|euc|sjis|utf8)$/oi && $1 or undef); + # 出力する漢字コードの選択 &DetectCode($cgi->param('CharCode')) or &DetectCode($KANJICODE) or &DetectCode('JIS'); $| = 1; @@ -90,6 +105,13 @@ $URL = $RURL = ($cgi->param('Method') =~ /^(?:Data|File)$/oi)? '': &htmllint::AbsoluteURL($ENV{HTTP_REFERER}, $cgi->param('URL')); +# 日本語文字が含まれている$URLをエラーメッセージの中に表示する場合に備え、 +# $URLの文字コードをスクリプトの文字コード($myCODE)に合わせておく。 +# さもないとフォームの文字コードが$myCODEと異なる場合に文字化けが起こる。 +# 現状ではフォームはUTF-8、スクリプトはEUC-JP/Shift_JISなので、 +# プライマリサイトなどでも実際に文字化けが発生しています。 +&Jconvert(\$URL, $myCODE, $formCODE); + # チェックオプションを得る &GetOptions; push @OPT, '-banner', '-score', '-w', 'long'; @@ -129,6 +151,9 @@ $HTML =~ s#/#:#og; $HTML = ($HTML =~ m#^:(.*)#)? $1: ':'.$HTML; } + # Windowsではopen()に渡すファイル名はShift_JISでなければならない + # なのでUnicode固有文字を名前に含むファイルなどは開けないことになる + &Jconvert(\$HTML, 'sjis', $myCODE) if $WIN; # %XXのデコードを行なう $HTML =~ s/\%([0-9A-Fa-f][0-9A-Fa-f])/pack('C', hex($1))/oge; } else { @@ -267,6 +292,23 @@ if ($FILE eq '') { &ErrorExit($msgNoFile); } $HTML = $cgi->tmpFileName($FILE); close($FILE); + + ## 送信フォームに「日本語を含むファイル名はチェックできないことがあります」 + ## と注意書きがあるが、この現象は、(1)CGI.pmのバージョンが2.42〜2.55、 + ## (2)フォームの文字コードがISO-2022-JP、(3)ファイル名に\x27(')が含まれる、 + ## の3条件が揃ったときに起こる。CGI.pmの2.56〜2.74では動作はするものの、 + ## 上記の条件ではファイル名の文字化けが発生する。 + ## このバグの原因は、CGI.pmがフォームから来たファイル名をそのままファイル + ## ハンドル名として利用していること。ファイル名に\x27(')が含まれる文字列を + ## ファイルハンドル名にしようとすると、'が勝手に::に置き換わってしまう。 + ## 他にも、\x22(")が含まれているとそこでファイル名が途切れてしまうバグ + ## (クォート処理が不完全なため)は最新版のCGI.pm(3.60)でも直っておらず、 + ## CGI.pmを使うときはフォームの文字コードにISO-2022-JPは使わない方が + ## 無難だと思われる。(以上解析結果) + # ここでの文字コード変換の必要性は上の$URLの場合と同様 + # $FILEはファイルハンドル兼用のオブジェクトなのでclose後に変換する + # オブジェクト$FILEを通常の文字列へ変換するために""が必要(演算子多重定義) + &Jconvert(\($FILE="$FILE"), $myCODE, $formCODE); push @OPT, '-usec'; } else { # TEXTEREAの内容をテンポラリに書く @@ -280,7 +322,7 @@ if (!(-e $HTML) || (-z $HTML)) { # テンポラリファイルがうまくできていない - my $japURL = (&Jgetcode(\$URL) =~ /^(jis|euc|sjis)$/)? 'URLに日本語などのASCII以外の文字を使うことはできません。': ''; + my $japURL = (&Jgetcode(\$URL) =~ /^(jis|euc|sjis|utf8)$/)? 'URLに日本語などのASCII以外の文字を使うことはできません。': ''; &Unlink; &EscapeRef(\$STAT); &EscapeRef(\$FILE);