From a335102e47abfa0317be75ca1271f4c01d626343 Mon Sep 17 00:00:00 2001 From: Hiroshi Shirosaki Date: Mon, 2 Dec 2019 14:56:17 +0900 Subject: [PATCH] Fix email address name encoding with ISO-2022-JP Convert to UTF-8 to split addresses correctly. Base64 encode ISO-2022-JP name. Add a unit test. --- program/include/rcmail_sendmail.php | 20 +++++++++++++++++++- tests/Framework/Charset.php | 25 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/program/include/rcmail_sendmail.php b/program/include/rcmail_sendmail.php index b90c23912..375d8b0c0 100644 --- a/program/include/rcmail_sendmail.php +++ b/program/include/rcmail_sendmail.php @@ -671,6 +671,10 @@ class rcmail_sendmail */ public function email_input_format($mailto, $count = false, $check = true) { + // convert to UTF-8 to preserve \x2c(,) and \x3b(;) used in ISO-2022-JP; + $charset = $this->options['charset']; + $mailto = rcube_charset::convert($mailto, $charset, RCUBE_CHARSET); + // simplified email regexp, supporting quoted local part $email_regexp = '(\S+|("[^"]+"))@\S+'; @@ -702,7 +706,21 @@ class rcmail_sendmail if ($name[0] == '"' && $name[strlen($name)-1] == '"') { $name = substr($name, 1, -1); } - $name = stripcslashes($name); + // encode "name" field. + if (function_exists('mb_encode_mimeheader') && $this->rcmail->config->get('head_encoding_base64')) { + $head_encoding_mode = 'B'; + $name = rcube_charset::convert($name, RCUBE_CHARSET, $charset); + $mb_charset = $charset; + if (rcube_charset::$mb_aliases[$charset]) { + $mb_charset = rcube_charset::$mb_aliases[$charset]; + } + mb_internal_encoding($mb_charset); + $name = preg_replace('/^"(.*)"$/', '$1', $name); + $name = mb_encode_mimeheader($name, $mb_charset, $head_encoding_mode, "\r\n", 8); + mb_internal_encoding(RCUBE_CHARSET); + } else { + $name = stripcslashes($name); + } $address = rcube_utils::idn_to_ascii(trim($address, '<>')); $result[] = format_email_recipient($address, $name); $item = $address; diff --git a/tests/Framework/Charset.php b/tests/Framework/Charset.php index 85cb4ba6c..491b9fe08 100644 --- a/tests/Framework/Charset.php +++ b/tests/Framework/Charset.php @@ -83,6 +83,31 @@ class Framework_Charset extends PHPUnit_Framework_TestCase $this->assertEquals($output, rcube_charset::convert($input, $from, $to)); } + /** + * Data for test_convert() + */ + function data_email_input_format() + { + return array( + array('ö', 'ö', 'UTF-8'), + array(base64_decode('GyRCLWo7M3l1OSk2SBsoQg=='), '㈱山﨑工業', 'ISO-2022-JP'), + ); + } + + /** + * @dataProvider data_email_input_format + */ + function test_email_input_format($input, $output, $charset) + { + $sendmail = new rcmail_sendmail(); + $sendmail->options['charset'] = $charset; + $sendmail->rcmail->config->set('head_encoding_base64', true); + $email = ' '; + $output = base64_encode(rcube_charset::convert($output, 'UTF-8', $charset)); + $output = '=?' . $charset . '?B?' . $output . '?=' . $email; + $this->assertEquals($output, $sendmail->email_input_format($input . $email)); + } + /** * Data for test_utf7_to_utf8() */