Follow up r75627. Implements r75670 in PHP to validate emails.
authorAntoine Musso <hashar@users.mediawiki.org>
Fri, 29 Oct 2010 22:03:17 +0000 (22:03 +0000)
committerAntoine Musso <hashar@users.mediawiki.org>
Fri, 29 Oct 2010 22:03:17 +0000 (22:03 +0000)
* 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
maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php [new file with mode: 0644]

index 22ea6dc..80ecd46 100644 (file)
@@ -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 (file)
index 0000000..4fdf142
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+
+class UserIsValidEmailAddrTest extends PHPUnit_Framework_TestCase {
+
+       private function testEmail( $addr, $expected = true, $msg = '') {
+               $this->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' );
+       }
+}