岩本隆史の日記帳(アーカイブ)

はてなダイアリーのサービス終了をうけて移行したものです。更新はしません。

SquirrelMailがメールヘッダのcharsetを見ずに文字化けするのでパッチを書いた

Squirrel Mailのダメなところは、メールのヘッダに書いてあるコーディングの情報を全て無視して、WebのUIの言語設定をそのまま使うところだ。

http://stlabwww.ssi.ist.hokudai.ac.jp/yuhyama/squirrel-ja-charset.html

同意。こうした実装になっている理由は調べていないけれど、メールヘッダのcharsetは信用できないということなのかな。その代わりに本文でmb_detect_encodingしているので、UTF-8なんかで送られたメールがたまに文字化けする。

メールヘッダを信用するパッチを、最新のSquirrelMail-1.4.15のソースに基づき書いてみた。

--- squirrelmail-1.4.15/functions/mime.php.org  2008-03-08 11:53:42.000000000 +0900
+++ squirrelmail-1.4.15/functions/mime.php  2008-06-20 00:15:47.061184000 +0900
@@ -329,9 +329,9 @@
 
         if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
                 function_exists($languages[$squirrelmail_language]['XTRA_CODE'])) {
-            if (mb_detect_encoding($body) != 'ASCII') {
-                $body = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $body);
-            }
+//            if (mb_detect_encoding($body) != 'ASCII') {
+                $body = $languages[$squirrelmail_language]['XTRA_CODE']('decode', $body, $body_message->header->getParameter('charset'));
+//            }
         }
         $hookResults = do_hook("message_body", $body);
         $body = $hookResults[1];


--- squirrelmail-1.4.15/functions/i18n.php.org  2008-05-20 18:15:08.000000000 +0900
+++ squirrelmail-1.4.15/functions/i18n.php  2008-06-20 00:18:43.895459200 +0900
@@ -571,6 +571,7 @@
     if (function_exists('mb_detect_encoding')) {
         switch (func_get_arg(0)) { /* action */
         case 'decode':
+/*
             $detect_encoding = @mb_detect_encoding($ret);
             if ($detect_encoding == 'JIS' ||
                 $detect_encoding == 'EUC-JP' ||
@@ -579,6 +580,17 @@
 
                 $ret = mb_convert_kana(mb_convert_encoding($ret, 'EUC-JP', 'AUTO'), "KV");
             }
+*/
+            $encoding = '';
+            if (count(func_get_args()) == 3) {
+                $encoding = func_get_arg(2);
+            }
+            if ($encoding == '') {
+                $encoding = @mb_detect_encoding($ret);
+            }
+            if ($encoding != '') {
+                $ret = mb_convert_kana(mb_convert_encoding($ret, 'EUC-JP', $encoding), 'KV', 'EUC-JP');
+            }
             break;
         case 'encode':
             $detect_encoding = @mb_detect_encoding($ret);

私は訳あって古いバージョンのSquirrelMailを使っているので、最新版での動作は未確認。ご利用は自己責任で。