note 83535 added to function.eregi
| From: | JeffMorris at osu1 dot php dot net | Date: | Fri, 30 May 2008 18:06:26 +0000 |
| Subject: | note 83535 added to function.eregi | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-140007@lists.php.net to get a copy of this message | ||
Email Address RegEx -- The Final Frontier?
Inspired by bobocop's stalwart effort. Cheers for that matey!
Contrary to most folks' expectation, a quoted @ character is permitted in the
local part of an email address. So strictly speaking bobocop's test result for
'@exam@exam.com' is ...inconclusive?
The RFC prohibits control characters in the address. So it's no coincidence
that most header-related exploits try to inject control characters into the
fields sent to the server. If we're validating client-side, we need to ensure
user input is restricted to the printable code set. And in the spirit of not
trusting anything inbound, we need to filter again server-side. It's handy
to have the same regex working at both ends.
My variant of bobocop's regex is listed below. Note the mask for the local
part matches any printable character *excluding the dot*. The dot is reserved
as a label separator. Bobocop's regex enforces that role while ensuring the
local part does not start or end with a dot.
Outside of the 7-bit ASCII and dot rules, the RFC says 'anything goes' in the
local part. Them's the breaks folks.
All we need to realise is that our endeavours are limited, and the nearest
we'll get to validating an email address is finding an MX record in DNS.
Whatever, don't go probing mail servers with test emails, you might get more
than you bargained for. That's sp@mmer territory, that is.
If you want to positively vet a mail server, consider running a check against
sbl-xbl.spamhaus.org. Search for the checkdnsrr function page on this site and
read the comments for good info.
Anyhoo, here's the modded regex builder:
//the variables
$local = '[\x20-\x2D\x2F-\x7E]';
$alnum = 'a-z0-9';
$domain = "([$alnum]([-$alnum]*[$alnum]+)?)";
//the array
$arr = array();
$arr['start'] = '^';
$arr['local'] = "$local+(\.$local+)*";
$arr['at'] = '@';
$arr['domain'] = "($domain{1,63}\.)+";
$arr['tld'] = "[$alnum]{2,6}";
$arr['end'] = '$';
//the regex
$regex = implode('',$arr);
/**
$regex evaluates to:
^[\x20-\x2D\x2F-\x7E]+(\.[\x20-\x2D\x2F-\x7E]+)*@
(([a-z0-9]([-a-z0-9]*[a-z0-9]+)?){1,63}\.)+[a-z0-9]{2,6}$
(regex split into 2 lines due to line length limits)
Add virgules front and back for the javascript equivalent.
I'm running this in an AJAX app right now and it does what it says on the tin.
If you're uncomfortable with the character length limits on domain and tld
names, change them to taste.
**/
----
Server IP: 87.124.64.96
Probable Submitter: 86.147.234.153
----
Manual Page -- http://www.php.net/manual/en/function.eregi.php
Edit -- https://master.php.net/note/edit/83535
Del: integrated -- https://master.php.net/note/delete/83535/integrated
Del: useless -- https://master.php.net/note/delete/83535/useless
Del: bad code -- https://master.php.net/note/delete/83535/bad+code
Del: spam -- https://master.php.net/note/delete/83535/spam
Del: non-english -- https://master.php.net/note/delete/83535/non-english
Del: in docs -- https://master.php.net/note/delete/83535/in+docs
Del: other reasons-- https://master.php.net/note/delete/83535
Reject -- https://master.php.net/note/reject/83535
Search -- https://master.php.net/manage/user-notes.php