Skip to content

Commit b1deef8

Browse files
committed
Reinstate the restriction that the sender's localpart must be all-ASCII.
This commit also adds a test that Symfony chooses IDN encoding when possible (to be compatible with all email receivers), and adjusts a couple of tests to match the name used in the main source code.
1 parent c11d6e0 commit b1deef8

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

src/Symfony/Component/Mailer/Envelope.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public static function create(RawMessage $message): self
4444

4545
public function setSender(Address $sender): void
4646
{
47+
// to ensure deliverability of bounce emails independent of UTF-8 capabilities of SMTP servers
48+
if (!preg_match('/^[^@\x80-\xFF]++@/', $sender->getAddress())) {
49+
throw new InvalidArgumentException(\sprintf('Invalid sender "%s": non-ASCII characters not supported in local-part of email.', $sender->getAddress()));
50+
}
4751
$this->sender = $sender;
4852
}
4953

src/Symfony/Component/Mailer/Tests/EnvelopeTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Mailer\Envelope;
16+
use Symfony\Component\Mailer\Exception\InvalidArgumentException;
1617
use Symfony\Component\Mailer\Exception\LogicException;
1718
use Symfony\Component\Mime\Address;
1819
use Symfony\Component\Mime\Header\Headers;
20+
use Symfony\Component\Mime\Header\PathHeader;
1921
use Symfony\Component\Mime\Message;
2022
use Symfony\Component\Mime\RawMessage;
2123

@@ -27,6 +29,13 @@ public function testConstructorWithAddressSender()
2729
$this->assertEquals(new Address('[email protected]'), $e->getSender());
2830
}
2931

32+
public function testConstructorWithAddressSenderAndNonAsciiCharactersInLocalPartOfAddress()
33+
{
34+
$this->expectException(InvalidArgumentException::class);
35+
$this->expectExceptionMessage('Invalid sender "fabiè[email protected]": non-ASCII characters not supported in local-part of email.');
36+
new Envelope(new Address('fabiè[email protected]'), [new Address('[email protected]')]);
37+
}
38+
3039
public function testConstructorWithNamedAddressSender()
3140
{
3241
$e = new Envelope($sender = new Address('[email protected]', 'Fabien'), [new Address('[email protected]')]);
@@ -72,6 +81,14 @@ public function testSenderFromHeaders()
7281
$this->assertEquals($from, $e->getSender());
7382
}
7483

84+
public function testSenderFromHeadersFailsWithNonAsciiCharactersInLocalPart()
85+
{
86+
$this->expectException(InvalidArgumentException::class);
87+
$this->expectExceptionMessage('Invalid sender "fabiè[email protected]": non-ASCII characters not supported in local-part of email.');
88+
$message = new Message(new Headers(new PathHeader('Return-Path', new Address('fabiè[email protected]'))));
89+
Envelope::create($message)->getSender();
90+
}
91+
7592
public function testSenderFromHeadersWithoutFrom()
7693
{
7794
$headers = new Headers();

src/Symfony/Component/Mailer/Tests/Transport/Smtp/EsmtpTransportTest.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,10 @@ public function testExtensibility()
6363
$this->assertContains("RCPT TO:<[email protected]> NOTIFY=FAILURE\r\n", $stream->getCommands());
6464
}
6565

66-
public function testSmtputf8()
66+
public function testSmtpUtf8()
6767
{
6868
$stream = new DummyStream();
69-
$transport = new Smtputf8EsmtpTransport(stream: $stream);
69+
$transport = new SmtpUtf8EsmtpTransport(stream: $stream);
7070

7171
$message = new Email();
7272
$message->from('info@dømi.fo');
@@ -79,7 +79,7 @@ public function testSmtputf8()
7979
$this->assertContains("RCPT TO:<dø[email protected]>\r\n", $stream->getCommands());
8080
}
8181

82-
public function testMissingSmtputf8()
82+
public function testMissingSmtpUtf8()
8383
{
8484
$stream = new DummyStream();
8585
$transport = new EsmtpTransport(stream: $stream);
@@ -94,6 +94,22 @@ public function testMissingSmtputf8()
9494
$transport->send($message);
9595
}
9696

97+
public function testSmtpUtf8FallbackToIDN()
98+
{
99+
$stream = new DummyStream();
100+
$transport = new EsmtpTransport(stream: $stream);
101+
102+
$message = new Email();
103+
$message->from('info@dømi.fo'); // UTF8 only in the domain
104+
$message->addTo('[email protected]');
105+
$message->text('.');
106+
107+
$transport->send($message);
108+
109+
$this->assertContains("MAIL FROM:<[email protected]>\r\n", $stream->getCommands());
110+
$this->assertContains("RCPT TO:<[email protected]>\r\n", $stream->getCommands());
111+
}
112+
97113
public function testConstructorWithDefaultAuthenticators()
98114
{
99115
$stream = new DummyStream();
@@ -303,7 +319,7 @@ public function executeCommand(string $command, array $codes): string
303319
}
304320
}
305321

306-
class Smtputf8EsmtpTransport extends EsmtpTransport
322+
class SmtpUtf8EsmtpTransport extends EsmtpTransport
307323
{
308324
public function executeCommand(string $command, array $codes): string
309325
{

0 commit comments

Comments
 (0)