diff --git a/core/lib/Drupal/Core/Mail/Plugin/Mail/PhpMail.php b/core/lib/Drupal/Core/Mail/Plugin/Mail/PhpMail.php index ad170d5707a0e48a9811d1ffb9e5323077ac9d67..e6728e51206ea7252cc7cdb774f6ebbabde196bb 100644 --- a/core/lib/Drupal/Core/Mail/Plugin/Mail/PhpMail.php +++ b/core/lib/Drupal/Core/Mail/Plugin/Mail/PhpMail.php @@ -109,10 +109,7 @@ public function mail(array $message) { // line-ending format appropriate for your system. If you need to // override this, adjust $settings['mail_line_endings'] in settings.php. $mail_body = preg_replace('@\r?\n@', $line_endings, $message['body']); - // For headers, PHP's API suggests that we use CRLF normally, - // but some MTAs incorrectly replace LF with CRLF. See #234403. - $mail_headers = str_replace("\r\n", "\n", $headers->toString()); - $mail_subject = str_replace("\r\n", "\n", $mail_subject); + $mail_headers = $headers->toString(); if (!$this->request->server->has('WINDIR') && !str_contains($this->request->server->get('SERVER_SOFTWARE'), 'Win32')) { // On most non-Windows systems, the "-f" option to the sendmail command diff --git a/core/tests/Drupal/Tests/Core/Mail/Plugin/Mail/PhpMailTest.php b/core/tests/Drupal/Tests/Core/Mail/Plugin/Mail/PhpMailTest.php index 1654db55a089dff4b2bdbf4c73137286b5f1cda6..abc7572b8eb37d745115eb8ae9628dab989d3940 100644 --- a/core/tests/Drupal/Tests/Core/Mail/Plugin/Mail/PhpMailTest.php +++ b/core/tests/Drupal/Tests/Core/Mail/Plugin/Mail/PhpMailTest.php @@ -77,9 +77,6 @@ protected function createPhpMailInstance(): PhpMail { ->onlyMethods(['doMail']) ->getMock(); - $mailer->expects($this->once())->method('doMail') - ->willReturn(TRUE); - $request = $this->getMockBuilder(Request::class) ->disableOriginalConstructor() ->getMock(); @@ -95,7 +92,6 @@ protected function createPhpMailInstance(): PhpMail { $reflection_property = $reflection->getProperty('request'); $reflection_property->setAccessible(TRUE); $reflection_property->setValue($mailer, $request); - return $mailer; } @@ -116,20 +112,43 @@ public function testMail() { 'langcode' => 'en', 'params' => [], 'send' => TRUE, - 'subject' => '', + 'subject' => "test\r\nsubject", 'body' => '', 'headers' => [ 'MIME-Version' => '1.0', 'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes', 'Content-Transfer-Encoding' => '8Bit', 'X-Mailer' => 'Drupal', - 'Return-Path' => 'from@example.org', 'From' => '"Foo, Bar, and Baz" <from@example.org>', 'Reply-to' => 'from@example.org', + 'Return-Path' => 'from@example.org', ], ]; $mailer = $this->createPhpMailInstance(); + + // Verify we use line endings consistent with the PHP mail() function, which + // changed with PHP 8. See: + // - https://www.drupal.org/node/3270647 + // - https://bugs.php.net/bug.php?id=81158 + $line_end = "\r\n"; + + $expected_headers = "MIME-Version: 1.0$line_end"; + $expected_headers .= "Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes$line_end"; + $expected_headers .= "Content-Transfer-Encoding: 8Bit$line_end"; + $expected_headers .= "X-Mailer: Drupal$line_end"; + $expected_headers .= "From: \"Foo, Bar, and Baz\" <from@example.org>$line_end"; + $expected_headers .= "Reply-to: from@example.org$line_end"; + + $mailer->expects($this->once())->method('doMail') + ->with( + $this->equalTo('to@example.org'), + $this->equalTo("=?utf-8?Q?test?={$line_end} =?utf-8?Q?subject?="), + $this->equalTo(''), + $this->stringStartsWith($expected_headers), + ) + ->willReturn(TRUE); + $this->assertTrue($mailer->mail($message)); }