diff --git a/ext/filter/filter.stub.php b/ext/filter/filter.stub.php index 5c0035e9a8406..d31423b4bcf4d 100644 --- a/ext/filter/filter.stub.php +++ b/ext/filter/filter.stub.php @@ -276,6 +276,11 @@ * @cname FILTER_FLAG_NO_PRIV_RANGE */ const FILTER_FLAG_NO_PRIV_RANGE = UNKNOWN; +/** + * @var int + * @cname FILTER_FLAG_GLOBAL_RANGE + */ +const FILTER_FLAG_GLOBAL_RANGE = UNKNOWN; /** * @var int diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h index eb347fce8fbf4..003c1a1da8aa9 100644 --- a/ext/filter/filter_arginfo.h +++ b/ext/filter/filter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: b37b1cee991d10a8198a3088a038b7ceea13d294 */ + * Stub hash: 85b9df04b0afa6404803c42e37fabe8c5b6265bb */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, input_type, IS_LONG, 0) @@ -113,6 +113,7 @@ static void register_filter_symbols(int module_number) REGISTER_LONG_CONSTANT("FILTER_FLAG_IPV6", FILTER_FLAG_IPV6, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_RES_RANGE", FILTER_FLAG_NO_RES_RANGE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_PRIV_RANGE", FILTER_FLAG_NO_PRIV_RANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_GLOBAL_RANGE", FILTER_FLAG_GLOBAL_RANGE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_HOSTNAME", FILTER_FLAG_HOSTNAME, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_EMAIL_UNICODE", FILTER_FLAG_EMAIL_UNICODE, CONST_CS | CONST_PERSISTENT); } diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h index d0eb010dd4854..a1bbb500f8db4 100644 --- a/ext/filter/filter_private.h +++ b/ext/filter/filter_private.h @@ -46,10 +46,11 @@ #define FILTER_FLAG_PATH_REQUIRED 0x040000 #define FILTER_FLAG_QUERY_REQUIRED 0x080000 -#define FILTER_FLAG_IPV4 0x100000 -#define FILTER_FLAG_IPV6 0x200000 -#define FILTER_FLAG_NO_RES_RANGE 0x400000 -#define FILTER_FLAG_NO_PRIV_RANGE 0x800000 +#define FILTER_FLAG_IPV4 0x00100000 +#define FILTER_FLAG_IPV6 0x00200000 +#define FILTER_FLAG_NO_RES_RANGE 0x00400000 +#define FILTER_FLAG_NO_PRIV_RANGE 0x00800000 +#define FILTER_FLAG_GLOBAL_RANGE 0x10000000 #define FILTER_FLAG_HOSTNAME 0x100000 diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 182f2b3cd0448..3f58b2a3c4fb1 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -897,7 +897,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } /* Check flags */ - if (flags & FILTER_FLAG_NO_PRIV_RANGE) { + if (flags & FILTER_FLAG_NO_PRIV_RANGE || flags & FILTER_FLAG_GLOBAL_RANGE) { if ( (ip[0] == 10) || (ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31) || @@ -907,7 +907,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } } - if (flags & FILTER_FLAG_NO_RES_RANGE) { + if (flags & FILTER_FLAG_NO_RES_RANGE || flags & FILTER_FLAG_GLOBAL_RANGE) { if ( (ip[0] == 0) || (ip[0] >= 240) || @@ -917,6 +917,20 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } } + + if (flags & FILTER_FLAG_GLOBAL_RANGE) { + if ( + (ip[0] == 100 && ip[1] >= 64 && ip[1] <= 127 ) || + (ip[0] == 192 && ip[1] == 0 && ip[2] == 0 ) || + (ip[0] == 192 && ip[1] == 0 && ip[2] == 2 ) || + (ip[0] == 198 && ip[1] >= 18 && ip[1] <= 19 ) || + (ip[0] == 198 && ip[1] == 51 && ip[2] == 100 ) || + (ip[0] == 203 && ip[1] == 0 && ip[2] == 113 ) + ) { + RETURN_VALIDATION_FAILED + } + } + break; case FORMAT_IPV6: @@ -927,14 +941,14 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } /* Check flags */ - if (flags & FILTER_FLAG_NO_PRIV_RANGE) { + if (flags & FILTER_FLAG_NO_PRIV_RANGE || flags & FILTER_FLAG_GLOBAL_RANGE) { if (ip[0] >= 0xfc00 && ip[0] <= 0xfdff) { RETURN_VALIDATION_FAILED } } - if (flags & FILTER_FLAG_NO_RES_RANGE) { + if (flags & FILTER_FLAG_NO_RES_RANGE || flags & FILTER_FLAG_GLOBAL_RANGE) { if ((ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 - && ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && (ip[7] == 0 || ip[7] == 1)) + && ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && (ip[7] == 0 || ip[7] == 1)) || (ip[0] == 0x5f) || (ip[0] >= 0xfe80 && ip[0] <= 0xfebf) || (ip[0] == 0x2001 && (ip[1] == 0x0db8 || (ip[1] >= 0x0010 && ip[1] <= 0x001f))) @@ -942,8 +956,18 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ ) { RETURN_VALIDATION_FAILED } - } - } + } + if (flags & FILTER_FLAG_GLOBAL_RANGE) { + if ((ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0 && ip[4] == 0 && ip[5] == 0xffff) || + (ip[0] == 0x0100 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) || + (ip[0] == 0x2001 && ip[1] <= 0x01ff) || + (ip[0] == 0x2001 && ip[1] == 0x0002 && ip[2] == 0) || + (ip[0] >= 0xfc00 && ip[0] <= 0xfdff) + ) { + RETURN_VALIDATION_FAILED + } + } + } break; } } diff --git a/ext/filter/tests/bug77221.phpt b/ext/filter/tests/bug77221.phpt new file mode 100644 index 0000000000000..307a83898ac44 --- /dev/null +++ b/ext/filter/tests/bug77221.phpt @@ -0,0 +1,121 @@ +--TEST-- +Bug #77221 (Request IP address filter flag to exclude non-global IP addresses) +--SKIPIF-- + +--FILE-- + $range) { + list($min, $max) = $range; + var_dump($key); + var_dump(filter_var($min, FILTER_VALIDATE_IP, FILTER_FLAG_GLOBAL_RANGE)); + var_dump(filter_var($max, FILTER_VALIDATE_IP, FILTER_FLAG_GLOBAL_RANGE)); +} + +var_dump(filter_var('185.85.0.29', FILTER_VALIDATE_IP, FILTER_FLAG_GLOBAL_RANGE)); +var_dump(filter_var('64:ff9b::', FILTER_VALIDATE_IP, FILTER_FLAG_GLOBAL_RANGE)); +var_dump(filter_var('64:ff9b::ffff', FILTER_VALIDATE_IP, FILTER_FLAG_GLOBAL_RANGE)); + +?> +--EXPECT-- +string(9) "0.0.0.0/8" +bool(false) +bool(false) +string(10) "10.0.0.0/8" +bool(false) +bool(false) +string(13) "100.64.0.0/10" +bool(false) +bool(false) +string(11) "127.0.0.0/8" +bool(false) +bool(false) +string(14) "169.254.0.0/16" +bool(false) +bool(false) +string(13) "172.16.0.0/12" +bool(false) +bool(false) +string(12) "192.0.0.0/24" +bool(false) +bool(false) +string(12) "192.0.2.0/24" +bool(false) +bool(false) +string(14) "192.168.0.0/16" +bool(false) +bool(false) +string(13) "198.18.0.0/15" +bool(false) +bool(false) +string(15) "198.51.100.0/24" +bool(false) +bool(false) +string(14) "203.0.113.0/24" +bool(false) +bool(false) +string(11) "240.0.0.0/4" +bool(false) +bool(false) +string(6) "::/128" +bool(false) +bool(false) +string(7) "::1/128" +bool(false) +bool(false) +string(13) "::ffff:0:0/96" +bool(false) +bool(false) +string(8) "100::/64" +bool(false) +bool(false) +string(9) "2001::/23" +bool(false) +bool(false) +string(11) "2001:2::/48" +bool(false) +bool(false) +string(13) "2001:db8::/32" +bool(false) +bool(false) +string(12) "2001:10::/28" +bool(false) +bool(false) +string(8) "fc00::/7" +bool(false) +bool(false) +string(9) "fe80::/10" +bool(false) +bool(false) +string(11) "185.85.0.29" +string(9) "64:ff9b::" +string(13) "64:ff9b::ffff"