From d31cb271170c0972be4220aed592aa2f5a23d699 Mon Sep 17 00:00:00 2001 From: Arnt Gulbrandsen Date: Tue, 8 Apr 2025 16:49:08 +0200 Subject: [PATCH] Adjust eai regex to disallow emoji and letters/numbers. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update a few tests to match the recent changes. Use the eai validator (unless another is being used) for addresses such as info@müller-schmidt.de, for which PHPMailer may not choose to use SMTPUTF8. --- src/PHPMailer.php | 12 ++++++------ test/PHPMailer/PHPMailerTest.php | 32 ++++++++++++++++++-------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/PHPMailer.php b/src/PHPMailer.php index cd96258f..47dd3022 100644 --- a/src/PHPMailer.php +++ b/src/PHPMailer.php @@ -1174,10 +1174,10 @@ class PHPMailer { if ( self::$validator === 'php' && - $this->addressHasUnicodeLocalPart($address) + ((bool) preg_match('/[\x80-\xFF]/', $address)) ) { - //The caller has not altered the validator, so assume that they want UTF-8 support - //instead of failing + //The caller has not altered the validator and is sending to an address + //with UTF-8, so assume that they want UTF-8 support instead of failing $this->CharSet = self::CHARSET_UTF8; self::$validator = 'eai'; } @@ -1467,9 +1467,9 @@ class PHPMailer * @see https://en.wikipedia.org/wiki/International_email */ return (bool) preg_match( - '/^[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~\x80-\xff-]+@[a-zA-Z0-9\x80-\xff](?:[a-zA-Z0-9\x80-\xff-]{0,61}' . - '[a-zA-Z0-9\x80-\xff])?(?:\.[a-zA-Z0-9\x80-\xff]' . - '(?:[a-zA-Z0-9\x80-\xff-]{0,61}[a-zA-Z0-9\x80-\xff])?)*$/sD', + '/^[-\p{L}\p{N}\p{M}.!#$%&\'*+\/=?^_`{|}~]+@[\p{L}\p{N}\p{M}](?:[\p{L}\p{N}\p{M}-]{0,61}' . + '[\p{L}\p{N}\p{M}])?(?:\.[\p{L}\p{N}\p{M}]' . + '(?:[-\p{L}\p{N}\p{M}]{0,61}[\p{L}\p{N}\p{M}])?)*$/usD', $address ); case 'php': diff --git a/test/PHPMailer/PHPMailerTest.php b/test/PHPMailer/PHPMailerTest.php index 889f364b..d2852230 100644 --- a/test/PHPMailer/PHPMailerTest.php +++ b/test/PHPMailer/PHPMailerTest.php @@ -1197,24 +1197,30 @@ EOT; */ public function testUnsupportedSmtpUTF8() { - $this->Mail = new PHPMailer(true); - $this->Mail->CharSet = PHPMailer::CHARSET_UTF8; - PHPMailer::$validator = 'html5'; - self::assertFalse(PHPMailer::validateAddress('spın̈altap@example.com')); - PHPMailer::$validator = 'eai'; - self::assertTrue(PHPMailer::validateAddress('spın̈altap@example.com')); + self::assertFalse(PHPMailer::validateAddress('spın̈altap@example.com', 'html5')); + self::assertTrue(PHPMailer::validateAddress('spın̈altap@example.com', 'eai')); } /** - * Test that SMTPUTF8 is automatically allowed if charset is UTF8. + * The eai regex is complex and warrants a few extra tests. + */ + public function testStrangeUnicodeEmailAddresses() + { + PHPMailer::$validator = 'eai'; + self::assertTrue(PHPMailer::validateAddress('spın̈altap@example.com')); + self::assertTrue(PHPMailer::validateAddress('spın̈altap@spın̈altap.com')); + self::assertTrue(PHPMailer::validateAddress('दूकान@मेरी.दूकान.भारत')); + self::assertTrue(PHPMailer::validateAddress('慕田峪长城@慕田峪长城.网址')); + self::assertFalse(PHPMailer::validateAddress('慕田峪长城@慕田峪长城。网址')); + } + + /** + * Test that SMTPUTF8 is allowed unless the caller has made a concious choice against. */ public function testAutomaticEaiValidation() { - $this->Mail->CharSet = PHPMailer::CHARSET_UTF8; - $this->Mail = new PHPMailer(true); PHPMailer::$validator = 'php'; - $this->Mail->CharSet = PHPMailer::CHARSET_UTF8; $this->Mail->Body = 'Test'; $this->Mail->isSMTP(); self::assertTrue($this->Mail->addAddress('spın̈altap@example.com', '')); @@ -1227,7 +1233,7 @@ EOT; */ public function testSmtpUTF8() { - PHPMailer::$validator = 'eai'; + PHPMailer::$validator = 'php'; $this->Mail = new PHPMailer(true); $this->Mail->Body = 'Test'; $this->Mail->isSMTP(); @@ -1235,15 +1241,13 @@ EOT; $this->Mail->preSend(); self::assertFalse($this->Mail->needsSMTPUTF8()); - //Using a punycoded domain does not need SMTPUTF8 + //Using a punycodable domain does not need SMTPUTF8 self::assertFalse($this->Mail->needsSMTPUTF8()); - PHPMailer::$validator = 'eai'; $this->Mail->addAddress('foo@spın̈altap.example', ''); $this->Mail->preSend(); self::assertFalse($this->Mail->needsSMTPUTF8()); //Need to use SMTPUTF8, and can. - $this->Mail->CharSet = PHPMailer::CHARSET_UTF8; self::assertTrue($this->Mail->addAddress('spın̈altap@example.com', '')); $this->Mail->preSend(); self::assertTrue($this->Mail->needsSMTPUTF8());