WordPress.org

Make WordPress Core

Ticket #19759: #19759.patch

File #19759.patch, 5.4 KB (added by arena, 2 years ago)

is_email to comply with RFC2822

  • wp-includes/formatting.php

     
    15321532/** 
    15331533 * Verifies that an email is valid. 
    15341534 * 
    1535  * Does not grok i18n domains. Not RFC compliant. 
     1535 * To comply with addr-spec of RFC 2822. (3.4.1. Addr-spec specification page 16) 
     1536 * code from swiftmailer.org 
    15361537 * 
    1537  * @since 0.71 
     1538 * @since 3.4 
    15381539 * 
    15391540 * @param string $email Email address to verify. 
    15401541 * @param boolean $deprecated Deprecated. 
     
    15441545        if ( ! empty( $deprecated ) ) 
    15451546                _deprecated_argument( __FUNCTION__, '3.0' ); 
    15461547 
    1547         // Test for the minimum length the email can be 
    1548         if ( strlen( $email ) < 3 ) { 
    1549                 return apply_filters( 'is_email', false, $email, 'email_too_short' ); 
    1550         } 
     1548        /*** Refer to RFC 2822 for ABNF grammar ***/ 
     1549     
     1550        //All basic building blocks 
     1551        $rfc2822['NO-WS-CTL'] = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]'; 
     1552        $rfc2822['WSP'] = '[ \t]'; 
     1553        $rfc2822['CRLF'] = '(?:\r\n)'; 
     1554        $rfc2822['FWS'] = '(?:(?:' . $rfc2822['WSP'] . '*' . $rfc2822['CRLF'] . ')?' . $rfc2822['WSP'] . ')'; 
     1555        $rfc2822['text'] = '[\x00-\x08\x0B\x0C\x0E-\x7F]'; 
     1556        $rfc2822['quoted-pair'] = '(?:\\\\' . $rfc2822['text'] . ')'; 
     1557        $rfc2822['ctext'] = '(?:' . $rfc2822['NO-WS-CTL'] . '|[\x21-\x27\x2A-\x5B\x5D-\x7E])'; 
     1558        $rfc2822['ccontent'] = '(?:' . $rfc2822['ctext'] . '|' . $rfc2822['quoted-pair'] . '|(?1))';            //Uses recursive PCRE (?1) 
     1559        $rfc2822['comment'] = '(\((?:' . $rfc2822['FWS'] . '|' . $rfc2822['ccontent']. ')*' . $rfc2822['FWS'] . '?\))'; 
     1560        $rfc2822['CFWS'] = '(?:(?:' . $rfc2822['FWS'] . '?' . $rfc2822['comment'] . ')*(?:(?:' . $rfc2822['FWS'] . '?' . $rfc2822['comment'] . ')|' . $rfc2822['FWS'] . '))'; 
     1561        $rfc2822['qtext'] = '(?:' . $rfc2822['NO-WS-CTL'] . '|[\x21\x23-\x5B\x5D-\x7E])'; 
     1562        $rfc2822['qcontent'] = '(?:' . $rfc2822['qtext'] . '|' . $rfc2822['quoted-pair'] . ')'; 
     1563        $rfc2822['quoted-string'] = '(?:' . $rfc2822['CFWS'] . '?"' . '(' . $rfc2822['FWS'] . '?' . $rfc2822['qcontent'] . ')*' . $rfc2822['FWS'] . '?"' . $rfc2822['CFWS'] . '?)'; 
     1564        $rfc2822['atext'] = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]'; 
     1565        $rfc2822['atom'] = '(?:' . $rfc2822['CFWS'] . '?' . $rfc2822['atext'] . '+' . $rfc2822['CFWS'] . '?)'; 
     1566        $rfc2822['dot-atom-text'] = '(?:' . $rfc2822['atext'] . '+' . '(\.' . $rfc2822['atext'] . '+)*)'; 
     1567        $rfc2822['dot-atom'] = '(?:' . $rfc2822['CFWS'] . '?' . $rfc2822['dot-atom-text'] . '+' . $rfc2822['CFWS'] . '?)'; 
     1568        $rfc2822['word'] = '(?:' . $rfc2822['atom'] . '|' . $rfc2822['quoted-string'] . ')'; 
     1569        $rfc2822['phrase'] = '(?:' . $rfc2822['word'] . '+?)'; 
     1570        $rfc2822['no-fold-quote'] = '(?:"(?:' . $rfc2822['qtext'] . '|' . $rfc2822['quoted-pair'] . ')*")'; 
     1571        $rfc2822['dtext'] = '(?:' . $rfc2822['NO-WS-CTL'] . '|[\x21-\x5A\x5E-\x7E])'; 
     1572        $rfc2822['no-fold-literal'] = '(?:\[(?:' . $rfc2822['dtext'] . '|' . $rfc2822['quoted-pair'] . ')*\])'; 
     1573        //Message IDs 
     1574        $rfc2822['id-left'] = '(?:' . $rfc2822['dot-atom-text'] . '|' . $rfc2822['no-fold-quote'] . ')'; 
     1575        $rfc2822['id-right'] = '(?:' . $rfc2822['dot-atom-text'] . '|' . $rfc2822['no-fold-literal'] . ')'; 
     1576        //Addresses, mailboxes and paths 
     1577        $rfc2822['local-part'] = '(?:' . $rfc2822['dot-atom'] . '|' . $rfc2822['quoted-string'] . ')'; 
     1578        $rfc2822['dcontent'] = '(?:' . $rfc2822['dtext'] . '|' . $rfc2822['quoted-pair'] . ')'; 
     1579        $rfc2822['domain-literal'] = '(?:' . $rfc2822['CFWS'] . '?\[(' . $rfc2822['FWS'] . '?' . $rfc2822['dcontent'] . ')*?' . $rfc2822['FWS'] . '?\]' . $rfc2822['CFWS'] . '?)'; 
     1580        $rfc2822['domain'] = '(?:' . $rfc2822['dot-atom'] . '|' . $rfc2822['domain-literal'] . ')'; 
     1581        $rfc2822['addr-spec'] = '(?:' . $rfc2822['local-part'] . '@' . $rfc2822['domain'] . ')'; 
    15511582 
    1552         // Test for an @ character after the first position 
    1553         if ( strpos( $email, '@', 1 ) === false ) { 
    1554                 return apply_filters( 'is_email', false, $email, 'email_no_at' ); 
    1555         } 
     1583        if ( preg_match( '/^' . $rfc2822['addr-spec'] . '$/D', $email ) ) 
     1584                        return apply_filters( 'is_email', $email, $email, null ); 
    15561585 
    1557         // Split out the local and domain parts 
    1558         list( $local, $domain ) = explode( '@', $email, 2 ); 
    1559  
    1560         // LOCAL PART 
    1561         // Test for invalid characters 
    1562         if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) { 
    1563                 return apply_filters( 'is_email', false, $email, 'local_invalid_chars' ); 
    1564         } 
    1565  
    1566         // DOMAIN PART 
    1567         // Test for sequences of periods 
    1568         if ( preg_match( '/\.{2,}/', $domain ) ) { 
    1569                 return apply_filters( 'is_email', false, $email, 'domain_period_sequence' ); 
    1570         } 
    1571  
    1572         // Test for leading and trailing periods and whitespace 
    1573         if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) { 
    1574                 return apply_filters( 'is_email', false, $email, 'domain_period_limits' ); 
    1575         } 
    1576  
    1577         // Split the domain into subs 
    1578         $subs = explode( '.', $domain ); 
    1579  
    1580         // Assume the domain will have at least two subs 
    1581         if ( 2 > count( $subs ) ) { 
    1582                 return apply_filters( 'is_email', false, $email, 'domain_no_periods' ); 
    1583         } 
    1584  
    1585         // Loop through each sub 
    1586         foreach ( $subs as $sub ) { 
    1587                 // Test for leading and trailing hyphens and whitespace 
    1588                 if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) { 
    1589                         return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' ); 
    1590                 } 
    1591  
    1592                 // Test for invalid characters 
    1593                 if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) { 
    1594                         return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' ); 
    1595                 } 
    1596         } 
    1597  
    1598         // Congratulations your email made it! 
    1599         return apply_filters( 'is_email', $email, $email, null ); 
     1586        return apply_filters( 'is_email', false, $email, 'not_RFC_2822_compliant' ); 
    16001587} 
    16011588 
    16021589/**