CakePHP 2.3.5 のメール送信で文字化けをしたら

CakePHP 2.3.5 のCakeEmailはバグっていて、ISO-2022-JPの特定の文字が入っているメールを送信しようとすると文字化け(というか、特定の文字列以降、その行がざっくりなくなる)します。

既に修正パッチを pull-request して、とりこまれているので、2.3.6 以降では治っていることになると思うんですが、取り急ぎ治したい人は以下のファイルを修正してください。

  • lib/Cake/Network/Email/CakeEmail.php の 1257 行目付近

修正前

        foreach ($lines as $line) {
            if (empty($line)) {
                $formatted[] = '';
                continue;
             } 
             if (!preg_match('/\<[a-z]/i', $line)) {

修正後

        foreach ($lines as $line) {
            if (empty($line)) {
                $formatted[] = '';
                continue;
            }
            if (strlen($line) < $wrapLength) {
                $formatted[] = $line;
                continue;
            } 
            if (!preg_match('/<[a-z]+.*>/i', $line)) {

修正ポイントは・・・

  • ISO-2022-JPの「受」のような特定の文字には「
  • このメソッドは第2引数の $wrapLength より長い場合に、その行に対してwrap処理をするためのものだから、$wrapLengthより短いならその行は処理しなくていいはず
  • そもそも「<」にエスケープいらなくね?

そもそも、wordwrap関数をかけてみたり、文字列を $line[$i] というように何バイト目?いうやり方でとってきたりと、マルチバイトで大丈夫か?という処理が行われているので、基本的にメールで送信する1行は 998 バイト以上にしないようにしといたほうがいいです。(998バイト以上になると、いろいろとヤバイ処理を通るので...)

今回はスルーした「その行にタグらしきものが入った場合」についても、おいおい処理内容をチェックして、マルチバイトでも大丈夫にしていこうかなと思っていたり、思ってなかったり...