Make WordPress Core

Changeset 10769


Ignore:
Timestamp:
03/11/2009 03:26:34 PM (17 years ago)
Author:
ryan
Message:

Improved is_email() and sanitize_email(). Props sambauers. fixes #9316 #4616

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/formatting.php

    r10767 r10769  
    12941294
    12951295/**
    1296  * Checks to see if the text is a valid email address.
     1296 * Verifies that an email is valid.
     1297 *
     1298 * Does not grok i18n domains. Not RFC compliant.
    12971299 *
    12981300 * @since 0.71
    12991301 *
    1300  * @param string $user_email The email address to be checked.
    1301  * @return bool Returns true if valid, otherwise false.
    1302  */
    1303 function is_email($user_email) {
    1304         $chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
    1305         if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) {
    1306                 if (preg_match($chars, $user_email)) {
    1307                         return true;
    1308                 } else {
    1309                         return false;
     1302 * @param string $email Email address to verify.
     1303 * @param boolean $check_dns Whether to check the DNS for the domain using checkdnsrr().
     1304 * @return string|bool Either false or the valid email address.
     1305 */
     1306function is_email( $email, $check_dns = false ) {
     1307        // Test for the minimum length the email can be
     1308        if ( strlen( $email ) < 3 ) {
     1309                return apply_filters( 'is_email', false, $email, 'email_too_short' );
     1310        }
     1311
     1312        // Test for an @ character after the first position
     1313        if ( strpos( $email, '@', 1 ) === false ) {
     1314                return apply_filters( 'is_email', false, $email, 'email_no_at' );
     1315        }
     1316
     1317        // Split out the local and domain parts
     1318        list( $local, $domain ) = explode( '@', $email, 2 );
     1319
     1320        // LOCAL PART
     1321        // Test for invalid characters
     1322        if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
     1323                return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
     1324        }
     1325
     1326        // DOMAIN PART
     1327        // Test for sequences of periods
     1328        if ( preg_match( '/\.{2,}/', $domain ) ) {
     1329                return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
     1330        }
     1331
     1332        // Test for leading and trailing periods and whitespace
     1333        if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
     1334                return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
     1335        }
     1336
     1337        // Split the domain into subs
     1338        $subs = explode( '.', $domain );
     1339
     1340        // Assume the domain will have at least two subs
     1341        if ( 2 > count( $subs ) ) {
     1342                return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
     1343        }
     1344
     1345        // Loop through each sub
     1346        foreach ( $subs as $sub ) {
     1347                // Test for leading and trailing hyphens and whitespace
     1348                if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
     1349                        return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
    13101350                }
    1311         } else {
    1312                 return false;
    1313         }
     1351
     1352                // Test for invalid characters
     1353                if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
     1354                        return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
     1355                }
     1356        }
     1357
     1358        // DNS
     1359        // Check the domain has a valid MX and A resource record
     1360        if ( $check_dns && function_exists( 'checkdnsrr' ) && !( checkdnsrr( $domain . '.', 'MX' ) || checkdnsrr( $domain . '.', 'A' ) ) ) {
     1361                return apply_filters( 'is_email', false, $email, 'dns_no_rr' );
     1362        }
     1363
     1364        // Congratulations your email made it!
     1365        return apply_filters( 'is_email', $email, $email, null );
    13141366}
    13151367
     
    14491501 * @return string Filtered email address.
    14501502 */
    1451 function sanitize_email($email) {
    1452         return preg_replace('/[^a-z0-9+_.@-]/i', '', $email);
     1503function sanitize_email( $email ) {
     1504        // Test for the minimum length the email can be
     1505        if ( strlen( $email ) < 3 ) {
     1506                return apply_filters( 'sanitize_email', '', $email, 'email_too_short' );
     1507        }
     1508
     1509        // Test for an @ character after the first position
     1510        if ( strpos( $email, '@', 1 ) === false ) {
     1511                return apply_filters( 'sanitize_email', '', $email, 'email_no_at' );
     1512        }
     1513
     1514        // Split out the local and domain parts
     1515        list( $local, $domain ) = explode( '@', $email, 2 );
     1516
     1517        // LOCAL PART
     1518        // Test for invalid characters
     1519        $local = preg_replace( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', '', $local );
     1520        if ( '' === $local ) {
     1521                return apply_filters( 'sanitize_email', '', $email, 'local_invalid_chars' );
     1522        }
     1523
     1524        // DOMAIN PART
     1525        // Test for sequences of periods
     1526        $domain = preg_replace( '/\.{2,}/', '', $domain );
     1527        if ( '' === $domain ) {
     1528                return apply_filters( 'sanitize_email', '', $email, 'domain_period_sequence' );
     1529        }
     1530
     1531        // Test for leading and trailing periods and whitespace
     1532        $domain = trim( $domain, " \t\n\r\0\x0B." );
     1533        if ( '' === $domain ) {
     1534                return apply_filters( 'sanitize_email', '', $email, 'domain_period_limits' );
     1535        }
     1536
     1537        // Split the domain into subs
     1538        $subs = explode( '.', $domain );
     1539
     1540        // Assume the domain will have at least two subs
     1541        if ( 2 > count( $subs ) ) {
     1542                return apply_filters( 'sanitize_email', '', $email, 'domain_no_periods' );
     1543        }
     1544
     1545        // Create an array that will contain valid subs
     1546        $new_subs = array();
     1547
     1548        // Loop through each sub
     1549        foreach ( $subs as $sub ) {
     1550                // Test for leading and trailing hyphens
     1551                $sub = trim( $sub, " \t\n\r\0\x0B-" );
     1552
     1553                // Test for invalid characters
     1554                $sub = preg_replace( '/^[^a-z0-9-]+$/i', '', $sub );
     1555
     1556                // If there's anything left, add it to the valid subs
     1557                if ( '' !== $sub ) {
     1558                        $new_subs[] = $sub;
     1559                }
     1560        }
     1561
     1562        // If there aren't 2 or more valid subs
     1563        if ( 2 > count( $new_subs ) ) {
     1564                return apply_filters( 'sanitize_email', '', $email, 'domain_no_valid_subs' );
     1565        }
     1566
     1567        // Join valid subs into the new domain
     1568        $domain = join( '.', $new_subs );
     1569
     1570        // Put the email back together
     1571        $email = $local . '@' . $domain;
     1572
     1573        // Congratulations your email made it!
     1574        return apply_filters( 'sanitize_email', $email, $email, null );
    14531575}
    14541576
Note: See TracChangeset for help on using the changeset viewer.