]> granicus.if.org Git - php/commitdiff
Support Unicode characters in the local part of an e-mail address.
authorLeo Feyer <github@contao.org>
Thu, 15 Oct 2015 09:07:25 +0000 (11:07 +0200)
committerAnatol Belski <ab@php.net>
Mon, 18 Jul 2016 19:52:35 +0000 (21:52 +0200)
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.

ext/filter/filter.c
ext/filter/filter_private.h
ext/filter/logical_filters.c
ext/filter/tests/058.phpt [new file with mode: 0644]

index 2c8dde9d49ae877877eccaf496c8f5a733b4f1c2..3d79a77f8a1fbba1db887981bf1bb66ef1784c91 100644 (file)
@@ -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;
index 2f9abc32bad12fc6bb4905dfb5f3d6c8adc727df..ffce723d52964d95a42b59bcf47708316af86180 100644 (file)
@@ -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
index 5fd057d5a911593f3c2f0215cc5674a5d14172ac..03d4795888199be3d89c2eb36b57400d5499b9a3 100644 (file)
@@ -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;
diff --git a/ext/filter/tests/058.phpt b/ext/filter/tests/058.phpt
new file mode 100644 (file)
index 0000000..a10f844
--- /dev/null
@@ -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ändsimple@example.com',
+'véry.çommon@example.com',
+'a.lîttle.lengthy.but.fiñe@dept.example.com',
+'dîsposable.style.émail.with+symbol@example.com',
+'other.émail-with-dash@example.com',
+'üser@[IPv6:2001:db8:1ff::a0b:dbd0]',
+'"verî.uñusual.@.uñusual.com"@example.com',
+'"verî.(),:;<>[]\".VERÎ.\"verî@\ \"verî\".unüsual"@strange.example.com',
+'tést@example.com',
+'tést.child@example.com',
+'tést@xn--exmple-cua.com',
+'tést@xn----zfa.xe',
+'tést@subexample.wizard',
+'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]',
+'tést+reference@example.com',
+'üñîçøðé@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ändsimple@example.com"
+string(25) "véry.çommon@example.com"
+string(44) "a.lîttle.lengthy.but.fiñe@dept.example.com"
+string(48) "dîsposable.style.émail.with+symbol@example.com"
+string(34) "other.émail-with-dash@example.com"
+string(35) "üser@[IPv6:2001:db8:1ff::a0b:dbd0]"
+string(43) ""verî.uñusual.@.uñusual.com"@example.com"
+string(74) ""verî.(),:;<>[]\".VERÎ.\"verî@\ \"verî\".unüsual"@strange.example.com"
+string(17) "tést@example.com"
+string(23) "tést.child@example.com"
+string(24) "tést@xn--exmple-cua.com"
+string(18) "tést@xn----zfa.xe"
+string(23) "tést@subexample.wizard"
+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ést+reference@example.com"
+string(26) "üñîçøðé@example.com"
+string(28) ""üñîçøðé"@example.com"
+string(31) "DžǼ੧ఘⅧ⒇৪@example.com"
+Done