#43402 [Com]: FILTER_VALIDATE_EMAIL is not RFC2822 compliant

From: Date: Wed, 17 Sep 2008 12:41:05 +0000
Subject: #43402 [Com]: FILTER_VALIDATE_EMAIL is not RFC2822 compliant
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-129057@lists.php.net to get a copy of this message
ID: 43402 Comment by: matt at mattfarina dot com Reported By: nobody at example dot org Status: Open Bug Type: Filter related Operating System: * PHP Version: 5.2.5 New Comment: RFC 2822 allows for email addresses like user@localhost or user@example. But, RFC 2821 (SMTP Standard) does not allow for those. See sections 4.1.2 and 4.13 for more detail. The question with email addresses is should we support RFC 2822 or 2821? For routing FILTER_VALIDATE_EMAIL currently follows RFC 2821. Previous Comments: ------------------------------------------------------------------------ [2008-09-16 20:00:59] matt at mattfarina dot com Please correct me if I'm wrong but isn't localhost an alias and RFC 2822 requires a fully qualified domain name or IP address. That would be the issue with foo@localhost. ------------------------------------------------------------------------ [2008-09-16 19:37:41] drewish at katherinehouse dot com The current code also bounces valid email addresses like "foo@localhost". I haven't been able to test out the suggested regex. ------------------------------------------------------------------------ [2007-11-26 14:23:55] nobody at example dot org Updated test, php_filter_validate_email() returns string on success. Surely bool would be a more appropriate return value for a logic filter? Updated regex above fixes the specific issue I was having, I'm uncertain about other edge cases (user\@site@example.org)? --TEST-- Bug 43402, RFC2822 allows chars (?, =) in dot-atoms --SKIPIF-- <?php if (!extension_loaded("filter")) die("skip"); ?> --FILE-- <?php $var="!#$%&'*+-/=.?^_`{|}~@[1.0.0.127]"; var_dump((bool)filter_var($var, FILTER_VALIDATE_EMAIL)); ?> --EXPECT-- bool(true) ------------------------------------------------------------------------ [2007-11-26 11:34:19] nobody at example dot org I may be missing something about the unit tests, following regex update to php_filter_validate_email() will not pass my test case (after doing rm ext/filter/tests/*.o ext/filter/tests/*.lo, clearing .out .log .exp .diff from tests and doing make; make test). const char regexp[] = "/^((\\\"[^\\\"\\f\\n\\r\\t\\b]+\\\")|([\\w\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\\\|\\{\\}\\=\\?]+(\\.[\\w\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\\\|\\{\\}\\=\\?]+)*))@((\\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\\-])+\\.)+[A-Za-z\\-]+))$/D"; Yet the equivalent regex works as expected in both PHP and my patched install. <?php error_reporting(E_ALL|E_STRICT); function validate_email($_) { /* Original from PEAR QuickForm Email.php rev: 1.4 */ $r = '/^((\"[^\"\f\n\r\t\v\b]+\")|([\w\!\#\$\%\&\'\*\+\-\~\/\^\\|\{\}\=\?]+(\.[\w\!\#\$\%\&\'\*\+\-\~\/\^\\|\{\}\=\?]+)*))@((\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9\-])+\.)+[A-Za-z\-]+))$/D'; return (bool) preg_match($r, $_); } $test = array('nobody@example.org'=>true, '.fails@example.org'=>false, "!#$%&'*+-/=.?^_`{|}~@[1.0.0.127]"=>true, ); $failed = 0; $fail = array(); foreach ($test as $k => $v){ if (!(validate_email($k) === $v)){ $failed++; $fail[].= $k; } } if ($failed > 0){ echo "Failed $failed of ",count($test), " tests using PHP func\n"; print_r($fail); } $failed = 0; $fail = array(); foreach ($test as $k => $v){ if (!((bool)filter_var($k, FILTER_VALIDATE_EMAIL) == (bool)$v)){ $failed++; $fail[].= $k; } } if ($failed > 0){ echo "Failed $failed of ",count($test), " tests using filter func\n"; print_r($fail); } ------------------------------------------------------------------------ [2007-11-25 23:46:34] nobody at example dot org --TEST-- RFC2822 conformance for local atoms --SKIPIF-- <?php if (!extension_loaded("filter")) die("skip"); ?> --FILE-- <?php $var = "!#$%&'*+-/=.?^_`{|}~@[1.0.0.127]"; var_dump(filter_var($var, FILTER_VALIDATE_EMAIL)); ?> --EXPECT-- bool(true) # Apologies for bug spam ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/43402 -- Edit this bug report at http://bugs.php.net/?id=43402&edit=1

« previous php.bugs (#129057) next »