From 0f3a919056dcc6a8c50b0831d0d8cfae79b6e8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Va=C5=88ura?= Date: Thu, 10 Oct 2024 10:40:05 +0200 Subject: [PATCH] MimePart: fixed not escaped header before encoded into utf-8 --- src/Mail/MimePart.php | 17 +++++++++++++++-- tests/Mail/Mail.headers.002.phpt | 4 ++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/Mail/MimePart.php b/src/Mail/MimePart.php index fcedb7f..b65b7c5 100644 --- a/src/Mail/MimePart.php +++ b/src/Mail/MimePart.php @@ -279,12 +279,21 @@ public function getEncodedMessage(): string */ private static function encodeSequence(string $s, int &$offset = 0, ?int $type = null): string { + $escape = static function (string $s): string { + // RFC 2822 atext except = + if (preg_match('#[^ a-zA-Z0-9!\#$%&\'*+/?^_`{|}~-]#', $s) === 1) { + return sprintf('"%s"', addcslashes($s, '"\\')); + } + + return $s; + }; + if ( (strlen($s) < self::LineLength - 3) && // 3 is tab + quotes strspn($s, "!\"#$%&\\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^`abcdefghijklmnopqrstuvwxyz{|}~=? _\r\n\t") === strlen($s) ) { - if ($type && preg_match('#[^ a-zA-Z0-9!\#$%&\'*+/?^_`{|}~-]#', $s)) { // RFC 2822 atext except = - return self::append('"' . addcslashes($s, '"\\') . '"', $offset); + if ($type !== null) { + $s = $escape($s); } return self::append($s, $offset); @@ -296,6 +305,10 @@ private static function encodeSequence(string $s, int &$offset = 0, ?int $type = $offset = 1; } + if ($type !== null) { + $s = $escape($s); + } + $s = iconv_mime_encode(str_repeat(' ', $old = $offset), $s, [ 'scheme' => 'B', // Q is broken 'input-charset' => 'UTF-8', diff --git a/tests/Mail/Mail.headers.002.phpt b/tests/Mail/Mail.headers.002.phpt index cfa634c..a3c4886 100644 --- a/tests/Mail/Mail.headers.002.phpt +++ b/tests/Mail/Mail.headers.002.phpt @@ -17,7 +17,7 @@ require __DIR__ . '/Mail.php'; $mail = new Message; -$mail->setFrom('John Doe '); +$mail->setFrom('Kdo uteče, obědvá '); $mail->addTo('Lady Jane '); $mail->addCc('jane@example.info'); @@ -37,7 +37,7 @@ Assert::match(<<<'EOD' MIME-Version: 1.0 X-Mailer: Nette Framework Date: %a% - From: John Doe + From: =?UTF-8?B?IktkbyB1dGXEjWUsIG9ixJtkdsOhIg==?= To: Lady Jane Cc: jane@example.info Bcc: bcc@example.com