Skip to content

Commit

Permalink
Support Unicode characters in the local part of an e-mail address.
Browse files Browse the repository at this point in the history
See RFC 6531 (https://tools.ietf.org/html/rfc6531).

Encode IDNA domains.

Add the missing "Done" to the expected output.

Add the FILTER_FLAG_EMAIL_RFC6531 flag.

Fix the filter_var() call.
  • Loading branch information
leofeyer authored and weltling committed Jul 18, 2016
1 parent 4226032 commit 8f40507
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 1 deletion.
2 changes: 2 additions & 0 deletions ext/filter/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,8 @@ PHP_MINIT_FUNCTION(filter)

REGISTER_LONG_CONSTANT("FILTER_FLAG_HOSTNAME", FILTER_FLAG_HOSTNAME, CONST_CS | CONST_PERSISTENT);

REGISTER_LONG_CONSTANT("FILTER_FLAG_EMAIL_RFC6531", FILTER_FLAG_EMAIL_RFC6531, CONST_CS | CONST_PERSISTENT);

sapi_register_input_filter(php_sapi_filter, php_sapi_filter_init);

return SUCCESS;
Expand Down
2 changes: 2 additions & 0 deletions ext/filter/filter_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@

#define FILTER_FLAG_HOSTNAME 0x100000

#define FILTER_FLAG_EMAIL_RFC6531 0x100000

#define FILTER_VALIDATE_INT 0x0101
#define FILTER_VALIDATE_BOOLEAN 0x0102
#define FILTER_VALIDATE_FLOAT 0x0103
Expand Down
7 changes: 6 additions & 1 deletion ext/filter/logical_filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,12 @@ void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
* Feel free to use and redistribute this code. But please keep this copyright notice.
*
*/
const char regexp[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";
if (flags & FILTER_FLAG_EMAIL_RFC6531) {
const char regexp[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E\\pL\\pN]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F\\pL\\pN]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iDu";
} else {
const char regexp[] = "/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD";
}

pcre *re = NULL;
pcre_extra *pcre_extra = NULL;
int preg_options = 0;
Expand Down
57 changes: 57 additions & 0 deletions ext/filter/tests/058.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
--TEST--
FILTER_VALIDATE_EMAIL unicode support (https://tools.ietf.org/html/rfc6531)
--SKIPIF--
<?php if (!extension_loaded("filter")) die("skip"); ?>
--FILE--
<?php
$values = Array(
'niceä[email protected]',
'véry.ç[email protected]',
'a.lîttle.lengthy.but.fiñ[email protected]',
'dîsposable.style.é[email protected]',
'other.é[email protected]',
'üser@[IPv6:2001:db8:1ff::a0b:dbd0]',
'"verî.uñ[email protected]ñusual.com"@example.com',
'"verî.(),:;<>[]\".VERÎ.\"verî@\ \"verî\".unüsual"@strange.example.com',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'tést@[255.255.255.255]',
'tést@[IPv6:2001:0db8:85a3:08d3:1319:8a2e:0370:7344]',
'tést@[IPv6:2001::7344]',
'tést@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]',
'[email protected]',
'üñîçøðé@example.com',
'"üñîçøðé"@example.com',
'DžǼ੧ఘⅧ⒇৪@example.com',
);
foreach ($values as $value) {
var_dump(filter_var($value, FILTER_VALIDATE_EMAIL, FILTER_FLAG_EMAIL_RFC6531));
}
echo "Done\n";
?>
--EXPECT--
string(26) "niceä[email protected]"
string(25) "véry.ç[email protected]"
string(44) "a.lîttle.lengthy.but.fiñ[email protected]"
string(48) "dîsposable.style.é[email protected]"
string(34) "other.é[email protected]"
string(35) "üser@[IPv6:2001:db8:1ff::a0b:dbd0]"
string(43) ""verî.uñ[email protected]ñusual.com"@example.com"
string(74) ""verî.(),:;<>[]\".VERÎ.\"verî@\ \"verî\".unüsual"@strange.example.com"
string(17) "té[email protected]"
string(23) "té[email protected]"
string(24) "té[email protected]"
string(18) "té[email protected]"
string(23) "té[email protected]"
string(23) "tést@[255.255.255.255]"
string(52) "tést@[IPv6:2001:0db8:85a3:08d3:1319:8a2e:0370:7344]"
string(23) "tést@[IPv6:2001::7344]"
string(58) "tést@[IPv6:1111:2222:3333:4444:5555:6666:255.255.255.255]"
string(27) "té[email protected]"
string(26) "üñîçøðé@example.com"
string(28) ""üñîçøðé"@example.com"
string(31) "DžǼ੧ఘⅧ⒇৪@example.com"
Done

0 comments on commit 8f40507

Please sign in to comment.