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());