From 1a0ffdbb354fd523b7021634b63f7e82f85c06ba Mon Sep 17 00:00:00 2001 From: Aleksei Khudiakov Date: Thu, 6 Apr 2017 06:18:43 +1000 Subject: [PATCH] Add support for internationalized email address local part --- src/EmailAddress.php | 20 ++++++++++++++++++++ test/EmailAddressTest.php | 4 +++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/EmailAddress.php b/src/EmailAddress.php index 7f06c2267..e6d1f5250 100644 --- a/src/EmailAddress.php +++ b/src/EmailAddress.php @@ -9,6 +9,8 @@ namespace Zend\Validator; +use UConverter; + class EmailAddress extends AbstractValidator { const INVALID = 'emailAddressInvalid'; @@ -342,6 +344,8 @@ protected function validateLocalPart() $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->localPart)) { $result = true; + } elseif ($this->validateInternationalizedLocalPart()) { + $result = true; } else { // Try quoted string format (RFC 5321 Chapter 4.1.2) @@ -360,6 +364,22 @@ protected function validateLocalPart() return $result; } + protected function validateInternationalizedLocalPart() + { + if ( + extension_loaded('intl') + && false === UConverter::transcode($this->localPart, 'UTF-8', 'UTF-8') + ) { + // invalid utf? + return false; + } + $atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d\x7e'; + // RFC 6532 extends atext to include non-ascii utf + // @see https://tools.ietf.org/html/rfc6532#section-3.1 + $uatext = $atext . '\x{80}-\x{FFFF}'; + return (bool) preg_match('/^[' . $uatext . ']+(\x2e+[' . $uatext . ']+)*$/u', $this->localPart); + } + /** * Returns the found MX Record information after validation including weight for further processing * diff --git a/test/EmailAddressTest.php b/test/EmailAddressTest.php index a13f3e0df..ece216988 100644 --- a/test/EmailAddressTest.php +++ b/test/EmailAddressTest.php @@ -235,6 +235,9 @@ public function validEmailAddresses() ]; if (extension_loaded('intl')) { + $return['иван@письмо.рф'] = ['иван@письмо.рф']; + $return['öäü@ä-umlaut.de'] = ['öäü@ä-umlaut.de']; + $return['frédéric@domain.com'] = ['frédéric@domain.com']; $return['bob@тест.рф'] = ['bob@тест.рф']; $return['bob@xn--e1aybc.xn--p1ai'] = ['bob@xn--e1aybc.xn--p1ai']; } @@ -277,7 +280,6 @@ public function invalidEmailAddresses() 'bob @ domain.com' => ['bob @ domain.com'], 'Abc..123@example.com' => ['Abc..123@example.com'], '"bob%jones@domain.com' => ['"bob%jones@domain.com'], - 'иван@письмо.рф' => ['иван@письмо.рф'], 'multiline' => ['bob @domain.com'],