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

git-svn-id: http://svn.automattic.com/wordpress/trunk@10769 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2009-03-11 15:26:34 +00:00
parent 04a572f4a7
commit 7ceebc2a27
1 changed files with 137 additions and 15 deletions

View File

@ -1293,24 +1293,76 @@ function convert_smilies($text) {
} }
/** /**
* Checks to see if the text is a valid email address. * Verifies that an email is valid.
*
* Does not grok i18n domains. Not RFC compliant.
* *
* @since 0.71 * @since 0.71
* *
* @param string $user_email The email address to be checked. * @param string $email Email address to verify.
* @return bool Returns true if valid, otherwise false. * @param boolean $check_dns Whether to check the DNS for the domain using checkdnsrr().
* @return string|bool Either false or the valid email address.
*/ */
function is_email($user_email) { function is_email( $email, $check_dns = false ) {
$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i"; // Test for the minimum length the email can be
if (strpos($user_email, '@') !== false && strpos($user_email, '.') !== false) { if ( strlen( $email ) < 3 ) {
if (preg_match($chars, $user_email)) { return apply_filters( 'is_email', false, $email, 'email_too_short' );
return true;
} else {
return false;
}
} else {
return false;
} }
// Test for an @ character after the first position
if ( strpos( $email, '@', 1 ) === false ) {
return apply_filters( 'is_email', false, $email, 'email_no_at' );
}
// Split out the local and domain parts
list( $local, $domain ) = explode( '@', $email, 2 );
// LOCAL PART
// Test for invalid characters
if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
}
// DOMAIN PART
// Test for sequences of periods
if ( preg_match( '/\.{2,}/', $domain ) ) {
return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
}
// Test for leading and trailing periods and whitespace
if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
}
// Split the domain into subs
$subs = explode( '.', $domain );
// Assume the domain will have at least two subs
if ( 2 > count( $subs ) ) {
return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
}
// Loop through each sub
foreach ( $subs as $sub ) {
// Test for leading and trailing hyphens and whitespace
if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
}
// Test for invalid characters
if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
}
}
// DNS
// Check the domain has a valid MX and A resource record
if ( $check_dns && function_exists( 'checkdnsrr' ) && !( checkdnsrr( $domain . '.', 'MX' ) || checkdnsrr( $domain . '.', 'A' ) ) ) {
return apply_filters( 'is_email', false, $email, 'dns_no_rr' );
}
// Congratulations your email made it!
return apply_filters( 'is_email', $email, $email, null );
} }
/** /**
@ -1448,8 +1500,78 @@ function popuplinks($text) {
* @param string $email Email address to filter. * @param string $email Email address to filter.
* @return string Filtered email address. * @return string Filtered email address.
*/ */
function sanitize_email($email) { function sanitize_email( $email ) {
return preg_replace('/[^a-z0-9+_.@-]/i', '', $email); // Test for the minimum length the email can be
if ( strlen( $email ) < 3 ) {
return apply_filters( 'sanitize_email', '', $email, 'email_too_short' );
}
// Test for an @ character after the first position
if ( strpos( $email, '@', 1 ) === false ) {
return apply_filters( 'sanitize_email', '', $email, 'email_no_at' );
}
// Split out the local and domain parts
list( $local, $domain ) = explode( '@', $email, 2 );
// LOCAL PART
// Test for invalid characters
$local = preg_replace( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', '', $local );
if ( '' === $local ) {
return apply_filters( 'sanitize_email', '', $email, 'local_invalid_chars' );
}
// DOMAIN PART
// Test for sequences of periods
$domain = preg_replace( '/\.{2,}/', '', $domain );
if ( '' === $domain ) {
return apply_filters( 'sanitize_email', '', $email, 'domain_period_sequence' );
}
// Test for leading and trailing periods and whitespace
$domain = trim( $domain, " \t\n\r\0\x0B." );
if ( '' === $domain ) {
return apply_filters( 'sanitize_email', '', $email, 'domain_period_limits' );
}
// Split the domain into subs
$subs = explode( '.', $domain );
// Assume the domain will have at least two subs
if ( 2 > count( $subs ) ) {
return apply_filters( 'sanitize_email', '', $email, 'domain_no_periods' );
}
// Create an array that will contain valid subs
$new_subs = array();
// Loop through each sub
foreach ( $subs as $sub ) {
// Test for leading and trailing hyphens
$sub = trim( $sub, " \t\n\r\0\x0B-" );
// Test for invalid characters
$sub = preg_replace( '/^[^a-z0-9-]+$/i', '', $sub );
// If there's anything left, add it to the valid subs
if ( '' !== $sub ) {
$new_subs[] = $sub;
}
}
// If there aren't 2 or more valid subs
if ( 2 > count( $new_subs ) ) {
return apply_filters( 'sanitize_email', '', $email, 'domain_no_valid_subs' );
}
// Join valid subs into the new domain
$domain = join( '.', $new_subs );
// Put the email back together
$email = $local . '@' . $domain;
// Congratulations your email made it!
return apply_filters( 'sanitize_email', $email, $email, null );
} }
/** /**