Index: trunk/phase3/maintenance/tests/phpunit/includes/UserIsValidEmailAddrTest.php |
— | — | @@ -0,0 +1,63 @@ |
| 2 | +<?php |
| 3 | + |
| 4 | +class UserIsValidEmailAddrTest extends PHPUnit_Framework_TestCase { |
| 5 | + |
| 6 | + private function testEmail( $addr, $expected = true, $msg = '') { |
| 7 | + $this->assertEquals( |
| 8 | + $expected, |
| 9 | + User::isValidEmailAddr( $addr ), |
| 10 | + $msg |
| 11 | + ); |
| 12 | + } |
| 13 | + private function valid( $addr, $msg = '' ) { |
| 14 | + $this->testEmail( $addr, true, $msg ); |
| 15 | + } |
| 16 | + private function invalid( $addr, $msg = '' ) { |
| 17 | + $this->testEmail( $addr, false, $msg ); |
| 18 | + } |
| 19 | + |
| 20 | + function testEmailWellKnownUserAtHostDotTldAreValid() { |
| 21 | + $this->valid( 'user@example.com' ); |
| 22 | + $this->valid( 'user@example.museum' ); |
| 23 | + } |
| 24 | + function testEmailWithUpperCaseCharactersAreValid() { |
| 25 | + $this->valid( 'USER@example.com' ); |
| 26 | + $this->valid( 'user@EXAMPLE.COM' ); |
| 27 | + $this->valid( 'user@Example.com' ); |
| 28 | + $this->valid( 'USER@eXAMPLE.com' ); |
| 29 | + } |
| 30 | + function testEmailWithAPlusInUserName() { |
| 31 | + $this->valid( 'user+sub@localdomain' ); |
| 32 | + } |
| 33 | + function testEmailWithWhiteSpacesBeforeOrAfterAreInvalids() { |
| 34 | + $this->invalid( " user@host" ); |
| 35 | + $this->invalid( "user@host " ); |
| 36 | + $this->invalid( "\tuser@host" ); |
| 37 | + $this->invalid( "user@host\t" ); |
| 38 | + } |
| 39 | + function testEmailWithWhiteSpacesAreInvalids() { |
| 40 | + $this->invalid( "User user@host" ); |
| 41 | + $this->invalid( "first last@mycompany" ); |
| 42 | + $this->invalid( "firstlast@my company" ); |
| 43 | + } |
| 44 | + function testEmailDomainCanNotBeginWithDot() { |
| 45 | + $this->invalid( "user@." ); |
| 46 | + $this->invalid( "user@.localdomain" ); |
| 47 | + $this->valid( "user@localdomain." ); |
| 48 | + $this->valid( "user.@localdomain" ); |
| 49 | + $this->valid( ".@localdomain" ); |
| 50 | + $this->valid( ".@a............" ); |
| 51 | + } |
| 52 | + function testEmailWithFunnyCharacters() { |
| 53 | + $this->valid( "\$user!ex{this}@123.com" ); |
| 54 | + } |
| 55 | + function testEmailTopLevelDomainCanBeNumerical() { |
| 56 | + $this->valid( "user@example.1234" ); |
| 57 | + } |
| 58 | + function testEmailWithoutAtSignIsInvalid() { |
| 59 | + $this->invalid( 'useràexample.com' ); |
| 60 | + } |
| 61 | + function testEmailWithOneCharacterDomainIsInvalid() { |
| 62 | + $this->invalid( 'user@a' ); |
| 63 | + } |
| 64 | +} |
Index: trunk/phase3/includes/User.php |
— | — | @@ -648,8 +648,19 @@ |
649 | 649 | if( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) { |
650 | 650 | return $result; |
651 | 651 | } |
| 652 | + $rfc5322_atext = "a-z0-9!#$%&'*+-\/=?^_`{|}—~" ; |
| 653 | + $rfc1034_ldh_str = "a-z0-9-" ; |
652 | 654 | |
653 | | - return strpos( $addr, '@' ) !== false; |
| 655 | + $HTML5_email_regexp = "/ |
| 656 | + ^ # start of string |
| 657 | + [$rfc5322_atext\\.]+ # user part which is liberal :p |
| 658 | + @ # 'apostrophe' |
| 659 | + [$rfc1034_ldh_str] # Domain first character |
| 660 | + [$rfc1034_ldh_str\\.]+ # Second char and following can include dot |
| 661 | + $ # End of string |
| 662 | + /ix" ; // case Insensitive, eXtended |
| 663 | + |
| 664 | + return (bool) preg_match( $HTML5_email_regexp, $addr ); |
654 | 665 | } |
655 | 666 | |
656 | 667 | /** |