mhonarc 日本語サブジェクト問題へのハック
2008年12月06日 15時20分18秒
これはなに?
メールボックスを mhonarc でHTML化した。するとMIMEエンコードされた日本語の件名に余分な空白が入り込む。 気になってしまったので、かなり泥臭い方法で対処した。その時のメモ書き。 ※というか、検索エンジンでうまくタイトルを引っ掛けられなかったため。
FreeBSD 7.0R のportsから導入した mhonarc-2.6.16_1 WWW front end for mail archives について説明している。
リンク
現象
メールの件名(Subject)がMIMEエンコードされているばあい、例えば
Subject: =?ISO-2022-JP?B?GyRCPCtGME8/MmghJk8/Mmg0ME47JWEhPCVrGyhC?=
のようなSubjectヘッダが付いている。これをデコードすると
Subject: 自動録画・録画完了メール
となる。
1行が長くなる場合、ヘッダの折り曲げが起こる。これはヘッダ1行の文字数が決められているため。例えば、
Subject: =?ISO-2022-JP?B?GyRCIVobKEpBSC1Tb2Z0GyRCJWElayVeJSwbKEogMhsoQg==?=
=?ISO-2022-JP?B?GyhKMDA4LzEyLzUbJEI5ZiFbJVQlcyUvJE4lUSVDJTEbKEI=?=
=?ISO-2022-JP?B?GyRCITwlOCQsTFwwdSEqISohKiFYGyhKV2ViIFZpZBsoQg==?=
=?ISO-2022-JP?B?GyhKZW8gRG93bmxvYWRlchskQiFZSC9HZDMrO08hKhsoQg==?=
=?ISO-2022-JP?B?GyRCISohKhsoQg==?=
の様になる。これをデコードすると
Subject: 【AH-Softメルマガ 2
008/12/5号】ピンクのパッケ
ージが目印!!!『Web Vid
eo Downloader』発売開始!
!!
となり、各行を1行につなげると
Subject: 【AH-Softメルマガ 2008/12/5号】ピンクのパッケージが目印!!!『Web Video Downloader』発売開始!!!
となる。
しかし、mhonarc がHTML化すると、Subjectが
Subject: 【AH-Softメルマガ 2 008/12/5号】ピンクのパッケ ージが目印!!!『Web Vid eo Downloader』発売開始! !!
となってしまう。
理由
mhonarc がSubjectを処理する際に、折り曲げ部分の先頭スペースも一緒に足しこんでしまうため。
解決方法
根本的解決ではないが、とりあえずしのぐ為の安直な手はある。
前提条件
- Subjectヘッダの折り曲げ部分先頭のスペースは空白もしくはタブの一文字だけであること。
これが崩れると、折り曲げ部分の先頭のスペースが件名で記述されたスペースなのか、折り曲げ部分先頭のスペースなのか判断ができなくなる。
概略
折り曲げされたヘッダの先頭スペースを無視すればいい。というか1行にしてしまえばいい。
Subject: =?ISO-2022-JP?B?GyRCIVobKEpBSC1Tb2Z0GyRCJWElayVeJSwbKEogMhsoQg==?=
=?ISO-2022-JP?B?GyhKMDA4LzEyLzUbJEI5ZiFbJVQlcyUvJE4lUSVDJTEbKEI=?=
=?ISO-2022-JP?B?GyRCITwlOCQsTFwwdSEqISohKiFYGyhKV2ViIFZpZBsoQg==?=
=?ISO-2022-JP?B?GyhKZW8gRG93bmxvYWRlchskQiFZSC9HZDMrO08hKhsoQg==?=
=?ISO-2022-JP?B?GyRCISohKhsoQg==?=
を
Subject: =?ISO-2022-JP?B?GyRCIVobKEpBSC1Tb2Z0GyRCJWElayVeJSwbKEogMhsoQg==?==?ISO-2022-JP?B?GyhKMDA4LzEyLzUbJEI5ZiFbJVQlcyUvJE4lUSVDJTEbKEI=?==?ISO-2022-JP?B?GyRCITwlOCQsTFwwdSEqISohKiFYGyhKV2ViIFZpZBsoQg==?==?ISO-2022-JP?B?GyhKZW8gRG93bmxvYWRlchskQiFZSC9HZDMrO08hKhsoQg==?==?ISO-2022-JP?B?GyRCISohKhsoQg==?=
の様に1行にまとめてから処理させる。ヘッダ1行の長さ制限に関しては、内部で厳密に処理していないようなので放置。 ※これはあくまでその場しのぎのHACKである。
readmail.plへのパッチ
FreeBSD 7.0R のportsからmhonarcを導入した場合、/usr/local/lib/perl5/site_perl/5.x.x に readmail.pl が導入されるので、これに以下のパッチを適用する。 5.x.x は導入してるperlのバージョンで違いがあると思うので各サイトごとに確認する。
www# diff -c readmail.pl.org readmail.pl
*** readmail.pl.org 2008-12-05 23:29:59.000000000 +0000
--- readmail.pl 2008-12-06 00:40:41.000000000 +0000
***************
*** 904,910 ****
my $fields = { };
local $/ = "\n";
! my($value, $tmp);
while (($tmp = <$handle>) !~ /^[\r]?$/) {
## Save raw text
$header .= $tmp;
--- 904,910 ----
my $fields = { };
local $/ = "\n";
! my($value, $tmp, $ss);
while (($tmp = <$handle>) !~ /^[\r]?$/) {
## Save raw text
$header .= $tmp;
***************
*** 912,917 ****
--- 912,941 ----
## Delete eol characters
$tmp =~ s/[\r\n]//g;
+ ## hack: Subject header merge
+ if ($tmp =~ /^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]:/) {
+ $ss = $tmp;
+ while (($tmp = <$handle>) !~ /^[\r]?$/) {
+ last if ($tmp =~ /^[^\t ]/);
+ $tmp =~ s/[\r\n]//g;
+ $tmp =~ s/^[\t ]//;
+ $ss .= $tmp;
+ }
+ if (defined($encfunc)) {
+ $ss = &MAILdecode_1522_str($ss,TEXT_ENCODE);
+ } elsif ($DecodeHeader) {
+ $ss = &MAILdecode_1522_str($ss,JUST_DECODE);
+ }
+ if ($ss =~ /^([^:\s]+):\s*([\s\S]*)$/) {
+ ($label, $value) = (lc($1), $2);
+ if (defined($fields->{$label})) {
+ push(@{$fields->{$label}}, $value);
+ } else {
+ $fields->{$label} = [ $value ];
+ }
+ }
+ }
+
## Decode text if requested
if (defined($encfunc)) {
$tmp = &MAILdecode_1522_str($tmp,TEXT_ENCODE);
関数 MAILread_file_header に追加している。
その他
あくまで、「これで何とかなっている」レベルなので、必ずテストはすること。 これを適用して問題が起きても私は知らない。