YANO's digital garage

Copyright ©YANO All rights reserved. https://www.bravotouring.com/~yano/

Last-modified: 2024-03-20 (水)


[一語一絵/IT系]

ウェブメーラー再び改修 / 2006-03-10 (金)

一昨日改修したばかりだが、またしても一部のSubjectがデコードされない問題発覚。

[External]WILLCOM『Pic@nic-Mail 通話明細照会内容更新のお知らせ』"=?ISO-2022-JP?Q?"だったので、mimir.pl の mimedecode に追加対処するなり。

## charset=`ISO-2022-JP',encoding=`Q' の encoded-word にマッチするパターン
$match_mime_qp = '=\?[Ii][Ss][Oo]-2022-[Jj][Pp]\?[Qq]\?([^\?]+)\?=';


## charset=`utf-8',encoding=`Q' の encoded-word にマッチするパターン
$match_mime_utf_qp = '=\?[Uu][Tt][Ff]-[78]\?[Qq]\?(.+)=*\?=';


## &bodydecode が使う処理残しデータ用バッファ
$bdebuf = "";

## mimedecode interface ##
sub main'mimedecode {
    local($_, $kout) = @_;
    1 while s/($match_mime)[ \t]*\n?[ \t]+($match_mime)/$1$3/o;
    s/$match_mime/&kconv(&base64decode($1))/geo;
    s/$match_mime_qp/&kconv(&qpdecode($1))/geo;
    s/$match_mime_utf_qp/&kconv(&qpdecode($1))/geo;
    s/(\x1b[\$\(][BHJ@])+/$1/g;
    1 while s/(\x1b\$[B@][\x21-\x7e]+)\x1b\$[B@]/$1/;
    1 while s/(\x1b\([BHJ][\t\x20-\x7e]+)\x1b\([BHJ]/$1/;
    s/^([\t\x20-\x7e]*)\x1b\([BHJ]/$1/;
    $_;
}
これだけなら何て事無かったのだが、さらに「途中から漢字が化ける」という難儀な問題が隠れていた。

4時間ほど頭をひねった結果、'<','>'の文字コードを含む漢字が化ける事に気付いた。"照"の7bits-JIS表現'>H'が、'&gt;H'とサニタイズされてたわけだ。MIMEデコードとUTF-8変換を済ませてからサニタイズするよう common_lib.pl の header_analysis を改修した。

sub header_analysis{
        my $header = $_[0];
        my %header_hash;
        my $i;

        my @tmp_array = split(/\r\n([^\:^\s]+)\s*:/, $header);
        shift(@tmp_array);
        for($i=0; $i<$#tmp_array; $i=$i+2){
                $key = $tmp_array[$i];
                $value = $tmp_array[($i+1)];

                $key = uc($key);
                &Jcode::convert(\$value, "euc");
# bug fix 2006/03/10
#               $value = deltag($value);
                $value =~ s/^\s*//;       # 先頭のスペースを削除
                $value =~ s/\r\n /\r\n/g; # スペースは改行の後のもののみ削除
                $value =~ s/\r\n//g; $value =~ s/\t//g;
#               &Jcode::convert(\$value, $charset);
#               $value = &mimedecode($value, $charset2);
                $value = &mimedecode($value);
                &Jcode::convert(\$value, $charset);
# bug fix 2006/03/10
                $value = deltag($value);

                if(($key eq 'TO' || $key eq 'CC' || $key eq 'REPLY-TO') && exists($header_hash{$key})){
                        $header_hash{$key} .= ", $value";
                }else{
                        $header_hash{$key} = $value;
                }
        }
        if(!exists($header_hash{'FROM'})){ $header_hash{'FROM'} = '(Fromなし)'; }
        if(!exists($header_hash{'SUBJECT'})){ $header_hash{'SUBJECT'} = '(Subjectなし)'; }
        if($header_hash{'SUBJECT'} eq ''){ $header_hash{'SUBJECT'} = '(空文字列のSubject)'; }

        return %header_hash;
}

【参照】
●竹田暁彦のホームページ http://www.ai.is.saga-u.ac.jp/~takeda/
ウェブメーラー
●@IT http://www.atmarkit.co.jp/
メールの文字コードを理解する 2006年2月18日
小規模オフィスのための無線LAN入門 第1回 無線LANの規格とセキュリティ 2006年2月3日
小規模オフィスのための無線LAN入門 第2回 アクセス・ポイントのセットアップ 2006年3月4日