From 011d4043a31f2142de4e5ddd31402eca3b55caa8 Mon Sep 17 00:00:00 2001 From: Antoine Musso Date: Fri, 29 Oct 2010 22:03:17 +0000 Subject: [PATCH] Follow up r75627. Implements r75670 in PHP to validate emails. * Server side validation of email according to an HTML5 specifications provided by Simetrical : http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state * This is NOT a fix of bug 959 (which wants RFC 2822 validation) * Basic unit tests --- includes/User.php | 15 ++++- .../includes/UserIsValidEmailAddrTest.php | 63 +++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php diff --git a/includes/User.php b/includes/User.php index 22ea6dcc5c..80ecd460b3 100644 --- a/includes/User.php +++ b/includes/User.php @@ -648,8 +648,19 @@ class User { if( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) { return $result; } - - return strpos( $addr, '@' ) !== false; + $rfc5322_atext = "a-z0-9!#$%&'*+-\/=?^_`{|}—~" ; + $rfc1034_ldh_str = "a-z0-9-" ; + + $HTML5_email_regexp = "/ + ^ # start of string + [$rfc5322_atext\\.]+ # user part which is liberal :p + @ # 'apostrophe' + [$rfc1034_ldh_str] # Domain first character + [$rfc1034_ldh_str\\.]+ # Second char and following can include dot + $ # End of string + /ix" ; // case Insensitive, eXtended + + return (bool) preg_match( $HTML5_email_regexp, $addr ); } /** diff --git a/maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php b/maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php new file mode 100644 index 0000000000..4fdf142dda --- /dev/null +++ b/maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php @@ -0,0 +1,63 @@ +assertEquals( + $expected, + User::isValidEmailAddr( $addr ), + $msg + ); + } + private function valid( $addr, $msg = '' ) { + $this->testEmail( $addr, true, $msg ); + } + private function invalid( $addr, $msg = '' ) { + $this->testEmail( $addr, false, $msg ); + } + + function testEmailWellKnownUserAtHostDotTldAreValid() { + $this->valid( 'user@example.com' ); + $this->valid( 'user@example.museum' ); + } + function testEmailWithUpperCaseCharactersAreValid() { + $this->valid( 'USER@example.com' ); + $this->valid( 'user@EXAMPLE.COM' ); + $this->valid( 'user@Example.com' ); + $this->valid( 'USER@eXAMPLE.com' ); + } + function testEmailWithAPlusInUserName() { + $this->valid( 'user+sub@localdomain' ); + } + function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { + $this->invalid( " user@host" ); + $this->invalid( "user@host " ); + $this->invalid( "\tuser@host" ); + $this->invalid( "user@host\t" ); + } + function testEmailWithWhiteSpacesAreInvalids() { + $this->invalid( "User user@host" ); + $this->invalid( "first last@mycompany" ); + $this->invalid( "firstlast@my company" ); + } + function testEmailDomainCanNotBeginWithDot() { + $this->invalid( "user@." ); + $this->invalid( "user@.localdomain" ); + $this->valid( "user@localdomain." ); + $this->valid( "user.@localdomain" ); + $this->valid( ".@localdomain" ); + $this->valid( ".@a............" ); + } + function testEmailWithFunnyCharacters() { + $this->valid( "\$user!ex{this}@123.com" ); + } + function testEmailTopLevelDomainCanBeNumerical() { + $this->valid( "user@example.1234" ); + } + function testEmailWithoutAtSignIsInvalid() { + $this->invalid( 'useràexample.com' ); + } + function testEmailWithOneCharacterDomainIsInvalid() { + $this->invalid( 'user@a' ); + } +} -- 2.20.1