Make WordPress Core


Ignore:
Timestamp:
03/11/2009 03:26:34 PM (15 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.