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