Make WordPress Core

Ticket #17491: #is_email_new_v3.patch

File #is_email_new_v3.patch, 8.2 KB (added by arena, 5 years ago)

v3 => to adhere to the coding standards

  • wp-includes/formatting.php

     
    32423242}
    32433243
    32443244/**
    3245  * Verifies that an email is valid.
    3246  *
    3247  * Does not grok i18n domains. Not RFC compliant.
    3248  *
    3249  * @since 0.71
    3250  *
    3251  * @param string $email      Email address to verify.
    3252  * @param bool   $deprecated Deprecated.
    3253  * @return string|bool Either false or the valid email address.
    3254  */
     3245* Verifies that an email is valid.
     3246*
     3247* @since 0.71
     3248*
     3249* @param string $email      Email address to verify.
     3250* @param bool   $deprecated Deprecated.
     3251* @return string|bool Either false or the valid email address.
     3252*/
    32553253function is_email( $email, $deprecated = false ) {
    32563254        if ( ! empty( $deprecated ) ) {
    32573255                _deprecated_argument( __FUNCTION__, '3.0.0' );
    32583256        }
    32593257
    3260         // Test for the minimum length the email can be
    3261         if ( strlen( $email ) < 6 ) {
    3262                 /**
    3263                  * Filters whether an email address is valid.
    3264                  *
    3265                  * This filter is evaluated under several different contexts, such as 'email_too_short',
    3266                  * 'email_no_at', 'local_invalid_chars', 'domain_period_sequence', 'domain_period_limits',
    3267                  * 'domain_no_periods', 'sub_hyphen_limits', 'sub_invalid_chars', or no specific context.
    3268                  *
    3269                  * @since 2.8.0
    3270                  *
    3271                  * @param bool   $is_email Whether the email address has passed the is_email() checks. Default false.
    3272                  * @param string $email    The email address being checked.
    3273                  * @param string $context  Context under which the email was tested.
    3274                  */
    3275                 return apply_filters( 'is_email', false, $email, 'email_too_short' );
     3258        switch( true ) {
     3259                case ( ! is_email_basics( $email ) ):
     3260                        return apply_filters( 'is_email', false, $email );
     3261                        break;
     3262                case ( is_email_rfc822(  $email ) ):
     3263                        break;
     3264                case ( is_email_rfc2822( $email ) ):
     3265                        break;
     3266                default:
     3267                        return apply_filters( 'is_email', false, $email );
    32763268        }
     3269        return $email;
     3270}
    32773271
    3278         // Test for an @ character after the first position
    3279         if ( strpos( $email, '@', 1 ) === false ) {
    3280                 /** This filter is documented in wp-includes/formatting.php */
    3281                 return apply_filters( 'is_email', false, $email, 'email_no_at' );
    3282         }
     3272/**
     3273* Verifies that email fits with basics.
     3274*
     3275*     the format of an email address is : local-part@domain-part
     3276*         the local  part may be up to 64 characters long and the domain may have a maximum of 255 characters.
     3277*         the domain part is a list of dot-separated DNS labels, each label being limited to a length of 63 characters
     3278*
     3279* @param string $email
     3280*/
     3281function is_email_basics( $email ) {
     3282        $parts = explode( '@', $email );
    32833283
    3284         // Split out the local and domain parts
    3285         list( $local, $domain ) = explode( '@', $email, 2 );
    3286 
    3287         // LOCAL PART
    3288         // Test for invalid characters
    3289         if ( ! preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
    3290                 /** This filter is documented in wp-includes/formatting.php */
    3291                 return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
     3284        $domain_part = array_pop( $parts );
     3285        if ( is_numeric( $domain_part ) ) {
     3286                return false;
    32923287        }
     3288        if ( strlen( $domain_part ) > 255 ) {
     3289                return false;
     3290        }
    32933291
    3294         // DOMAIN PART
    3295         // Test for sequences of periods
    3296         if ( preg_match( '/\.{2,}/', $domain ) ) {
    3297                 /** This filter is documented in wp-includes/formatting.php */
    3298                 return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
     3292        $local_part  = implode( '@', $parts );
     3293        if ( strlen( $local_part ) > 64 ) {
     3294                return false;
    32993295        }
    33003296
    3301         // Test for leading and trailing periods and whitespace
    3302         if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
    3303                 /** This filter is documented in wp-includes/formatting.php */
    3304                 return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
     3297        $dots = explode( '.', $domain_part );
     3298        foreach( $dots as $dot ) {
     3299                if ( strlen( $dot ) > 63 ) {
     3300                        return false;
     3301                }
    33053302        }
     3303        return true;
     3304}
    33063305
    3307         // Split the domain into subs
    3308         $subs = explode( '.', $domain );
    3309 
    3310         // Assume the domain will have at least two subs
    3311         if ( 2 > count( $subs ) ) {
    3312                 /** This filter is documented in wp-includes/formatting.php */
    3313                 return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
     3306/**
     3307*  Validates whether the value is a valid e-mail address.
     3308*       In general, this validates e-mail addresses against the syntax in RFC 822,
     3309*    with the exceptions that comments and whitespace folding and dotless domain names are not supported.
     3310*  [php.net]
     3311*
     3312* @param string $email
     3313*/
     3314function is_email_rfc822( $email ) {
     3315        if ( ! defined( 'FILTER_VALIDATE_EMAIL' ) ) {
     3316                return false;
    33143317        }
     3318        if ( ! function_exists( 'filter_var' ) ) {
     3319                return false;
     3320        }
     3321        return ( filter_var( $email, FILTER_VALIDATE_EMAIL ) );
     3322}
    33153323
    3316         // Loop through each sub
    3317         foreach ( $subs as $sub ) {
    3318                 // Test for leading and trailing hyphens and whitespace
    3319                 if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
    3320                         /** This filter is documented in wp-includes/formatting.php */
    3321                         return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
    3322                 }
     3324/**
     3325* Defines and applies the grammar to use for validation, implements the RFC 2822 (and friends) ABNF grammar definitions.
     3326*
     3327* @author     Fabien Potencier
     3328* @author     Chris Corbyn
     3329*
     3330* @param string $email
     3331*/
     3332function is_email_rfc2822( $email ) {
     3333        return ( preg_match( '/^' . is_email_rfc2822_grammar() . '$/D', $email ) );
     3334}
    33233335
    3324                 // Test for invalid characters
    3325                 if ( ! preg_match( '/^[a-z0-9-]+$/i', $sub ) ) {
    3326                         /** This filter is documented in wp-includes/formatting.php */
    3327                         return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
    3328                 }
    3329         }
     3336/**
     3337* Refer to RFC 2822 for ABNF grammar
     3338*
     3339* @author     Fabien Potencier
     3340* @author     Chris Corbyn
     3341*
     3342*/
     3343function is_email_rfc2822_grammar() {
     3344        //All basic building blocks
     3345        $g['NO-WS-CTL']         = '[\x01-\x08\x0B\x0C\x0E-\x19\x7F]';
     3346        $g['WSP']                       = '[ \t]';
     3347        $g['CRLF']              = '(?:\r\n)';
     3348        $g['FWS']                       = '(?:(?:' . $g['WSP'] . '*' . $g['CRLF'] . ')?' . $g['WSP'] . ')';
     3349        $g['text']              = '[\x00-\x08\x0B\x0C\x0E-\x7F]';
     3350        $g['quoted-pair']       = '(?:\\\\' . $g['text'] . ')';
     3351        $g['ctext']             = '(?:' . $g['NO-WS-CTL'] . '|[\x21-\x27\x2A-\x5B\x5D-\x7E])';
     3352        //Uses recursive PCRE (?1) --
     3353        $g['ccontent']          = '(?:' . $g['ctext'] . '|' . $g['quoted-pair'] . '|(?1))';
     3354        $g['comment']           = '(\((?:' . $g['FWS'] . '|' . $g['ccontent']. ')*' . $g['FWS'] . '?\))';
     3355        $g['CFWS']              = '(?:(?:' . $g['FWS'] . '?' . $g['comment'] . ')*(?:(?:' . $g['FWS'] . '?' . $g['comment'] . ')|' . $g['FWS'] . '))';
     3356        $g['qtext']             = '(?:' . $g['NO-WS-CTL'] . '|[\x21\x23-\x5B\x5D-\x7E])';
     3357        $g['qcontent']          = '(?:' . $g['qtext'] . '|' . $g['quoted-pair'] . ')';
     3358        $g['quoted-string']     = '(?:' . $g['CFWS'] . '?"' . '(' . $g['FWS'] . '?' . $g['qcontent'] . ')*' . $g['FWS'] . '?"' . $g['CFWS'] . '?)';
     3359        $g['atext']             = '[a-zA-Z0-9!#\$%&\'\*\+\-\/=\?\^_`\{\}\|~]';
     3360        $g['atom']              = '(?:' . $g['CFWS'] . '?' . $g['atext'] . '+' . $g['CFWS'] . '?)';
     3361        $g['dot-atom-text']     = '(?:' . $g['atext'] . '+' . '(\.' . $g['atext'] . '+)*)';
     3362        $g['dot-atom']          = '(?:' . $g['CFWS'] . '?' . $g['dot-atom-text'] . '+' . $g['CFWS'] . '?)';
     3363        $g['word']              = '(?:' . $g['atom'] . '|' . $g['quoted-string'] . ')';
     3364        $g['phrase']            = '(?:' . $g['word'] . '+?)';
     3365        $g['no-fold-quote']     = '(?:"(?:' . $g['qtext'] . '|' . $g['quoted-pair'] . ')*")';
     3366        $g['dtext']             = '(?:' . $g['NO-WS-CTL'] . '|[\x21-\x5A\x5E-\x7E])';
     3367        $g['no-fold-literal']   = '(?:\[(?:' . $g['dtext'] . '|' . $g['quoted-pair'] . ')*\])';
     3368        //Message IDs
     3369        $g['id-left']           = '(?:' . $g['dot-atom-text'] . '|' . $g['no-fold-quote'] . ')';
     3370        $g['id-right']          = '(?:' . $g['dot-atom-text'] . '|' . $g['no-fold-literal'] . ')';
     3371        //Addresses, mailboxes and paths
     3372        $g['local-part']        = '(?:' . $g['dot-atom'] . '|' . $g['quoted-string'] . ')';
     3373        $g['dcontent']          = '(?:' . $g['dtext'] . '|' . $g['quoted-pair'] . ')';
     3374        $g['domain-literal']    = '(?:' . $g['CFWS'] . '?\[(' . $g['FWS'] . '?' . $g['dcontent'] . ')*?' . $g['FWS'] . '?\]' . $g['CFWS'] . '?)';
     3375        $g['domain']            = '(?:' . $g['dot-atom'] . '|' . $g['domain-literal'] . ')';
    33303376
    3331         // Congratulations your email made it!
    3332         /** This filter is documented in wp-includes/formatting.php */
    3333         return apply_filters( 'is_email', $email, $email, null );
     3377        return '(?:' . $g['local-part'] . '@' . $g['domain'] . ')';
    33343378}
    33353379
    33363380/**