mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: Fix #61700: FILTER_FLAG_IPV6/FILTER_FLAG_NO_PRIV|RES_RANGE failing
This commit is contained in:
commit
1dcc0ff5f6
4
NEWS
4
NEWS
@ -2,6 +2,10 @@ PHP NEWS
|
||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.1.0RC3
|
||||
|
||||
- Filter:
|
||||
. Fixed bug #61700 (FILTER_FLAG_IPV6/FILTER_FLAG_NO_PRIV|RES_RANGE failing).
|
||||
(cmb, Nikita)
|
||||
|
||||
- Reflection:
|
||||
. Fixed bug #81457 (Enum: ReflectionMethod->getDeclaringClass() return a
|
||||
ReflectionClass). (Nikita)
|
||||
|
@ -89,7 +89,7 @@
|
||||
#define FORMAT_IPV4 4
|
||||
#define FORMAT_IPV6 6
|
||||
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len);
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]);
|
||||
|
||||
static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */
|
||||
zend_long ctx_value;
|
||||
@ -613,7 +613,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
t = e - 1;
|
||||
|
||||
/* An IPv6 enclosed by square brackets is a valid hostname */
|
||||
if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2)) {
|
||||
if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) {
|
||||
php_url_free(url);
|
||||
return;
|
||||
}
|
||||
@ -753,11 +753,11 @@ static int _php_filter_validate_ipv4(char *str, size_t str_len, int *ip) /* {{{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len) /* {{{ */
|
||||
static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]) /* {{{ */
|
||||
{
|
||||
int compressed = 0;
|
||||
int compressed_pos = -1;
|
||||
int blocks = 0;
|
||||
int n;
|
||||
int num, n, i;
|
||||
char *ipv4;
|
||||
char *end;
|
||||
int ip4elm[4];
|
||||
@ -800,35 +800,67 @@ static int _php_filter_validate_ipv6(char *str, size_t str_len) /* {{{ */
|
||||
return 0;
|
||||
}
|
||||
if (*str == ':') {
|
||||
if (compressed) {
|
||||
if (compressed_pos >= 0) {
|
||||
return 0;
|
||||
}
|
||||
blocks++; /* :: means 1 or more 16-bit 0 blocks */
|
||||
compressed = 1;
|
||||
|
||||
if (ip && blocks < 8) {
|
||||
ip[blocks] = -1;
|
||||
}
|
||||
compressed_pos = blocks++; /* :: means 1 or more 16-bit 0 blocks */
|
||||
if (++str == end) {
|
||||
return (blocks <= 8);
|
||||
if (blocks > 8) {
|
||||
return 0;
|
||||
}
|
||||
goto fixup_ip;
|
||||
}
|
||||
} else if ((str - 1) == s) {
|
||||
/* don't allow leading : without another : following */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
n = 0;
|
||||
while ((str < end) &&
|
||||
((*str >= '0' && *str <= '9') ||
|
||||
(*str >= 'a' && *str <= 'f') ||
|
||||
(*str >= 'A' && *str <= 'F'))) {
|
||||
num = n = 0;
|
||||
while (str < end) {
|
||||
if (*str >= '0' && *str <= '9') {
|
||||
num = 16 * num + (*str - '0');
|
||||
} else if (*str >= 'a' && *str <= 'f') {
|
||||
num = 16 * num + (*str - 'a') + 10;
|
||||
} else if (*str >= 'A' && *str <= 'F') {
|
||||
num = 16 * num + (*str - 'A') + 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
str++;
|
||||
}
|
||||
if (ip && blocks < 8) {
|
||||
ip[blocks] = num;
|
||||
}
|
||||
if (n < 1 || n > 4) {
|
||||
return 0;
|
||||
}
|
||||
if (++blocks > 8)
|
||||
return 0;
|
||||
}
|
||||
return ((compressed && blocks <= 8) || blocks == 8);
|
||||
|
||||
fixup_ip:
|
||||
if (ip && ipv4) {
|
||||
for (i = 0; i < 5; i++) {
|
||||
ip[i] = 0;
|
||||
}
|
||||
ip[i++] = 0xffff;
|
||||
ip[i++] = 256 * ip4elm[0] + ip4elm[1];
|
||||
ip[i++] = 256 * ip4elm[2] + ip4elm[3];
|
||||
} else if (ip && compressed_pos >= 0 && blocks <= 8) {
|
||||
int offset = 8 - blocks;
|
||||
for (i = 7; i > compressed_pos + offset; i--) {
|
||||
ip[i] = ip[i - offset];
|
||||
}
|
||||
for (i = compressed_pos + offset; i >= compressed_pos; i--) {
|
||||
ip[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (compressed_pos >= 0 && blocks <= 8) || blocks == 8;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -839,7 +871,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
* allow_ipv4 and allow_ipv6 flags flag are used, then the first dot or
|
||||
* colon determine the format */
|
||||
|
||||
int ip[4];
|
||||
int ip[8];
|
||||
int mode;
|
||||
|
||||
if (memchr(Z_STRVAL_P(value), ':', Z_STRLEN_P(value))) {
|
||||
@ -890,52 +922,28 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
|
||||
case FORMAT_IPV6:
|
||||
{
|
||||
int res = 0;
|
||||
res = _php_filter_validate_ipv6(Z_STRVAL_P(value), Z_STRLEN_P(value));
|
||||
res = _php_filter_validate_ipv6(Z_STRVAL_P(value), Z_STRLEN_P(value), ip);
|
||||
if (res < 1) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
/* Check flags */
|
||||
if (flags & FILTER_FLAG_NO_PRIV_RANGE) {
|
||||
if (Z_STRLEN_P(value) >=2 && (!strncasecmp("FC", Z_STRVAL_P(value), 2) || !strncasecmp("FD", Z_STRVAL_P(value), 2))) {
|
||||
if (ip[0] >= 0xfc00 && ip[0] <= 0xfdff) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
}
|
||||
if (flags & FILTER_FLAG_NO_RES_RANGE) {
|
||||
switch (Z_STRLEN_P(value)) {
|
||||
case 1: case 0:
|
||||
break;
|
||||
case 2:
|
||||
if (zend_string_equals_literal(Z_STR_P(value), "::")) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (zend_string_equals_literal(Z_STR_P(value), "::1") || zend_string_equals_literal(Z_STR_P(value), "5f:")) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (Z_STRLEN_P(value) >= 5) {
|
||||
if (
|
||||
!strncasecmp("fe8", Z_STRVAL_P(value), 3) ||
|
||||
!strncasecmp("fe9", Z_STRVAL_P(value), 3) ||
|
||||
!strncasecmp("fea", Z_STRVAL_P(value), 3) ||
|
||||
!strncasecmp("feb", Z_STRVAL_P(value), 3)
|
||||
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[0] == 0x5f)
|
||||
|| (ip[0] >= 0xfe80 && ip[0] <= 0xfebf)
|
||||
|| ((ip[0] == 0x2001 && ip[1] == 0x0db8) || (ip[1] >= 0x0010 && ip[1] <= 0x001f))
|
||||
|| (ip[0] == 0x3ff3)
|
||||
) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
}
|
||||
if (
|
||||
(Z_STRLEN_P(value) >= 9 && !strncasecmp("2001:0db8", Z_STRVAL_P(value), 9)) ||
|
||||
(Z_STRLEN_P(value) >= 2 && !strncasecmp("5f", Z_STRVAL_P(value), 2)) ||
|
||||
(Z_STRLEN_P(value) >= 4 && !strncasecmp("3ff3", Z_STRVAL_P(value), 4)) ||
|
||||
(Z_STRLEN_P(value) >= 8 && !strncasecmp("2001:001", Z_STRVAL_P(value), 8))
|
||||
) {
|
||||
RETURN_VALIDATION_FAILED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ var_dump(filter_var("::", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
var_dump(filter_var("::", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
|
||||
var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
var_dump(filter_var("::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
|
||||
var_dump(filter_var("fe8:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
var_dump(filter_var("fe8:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
|
||||
var_dump(filter_var("fe80:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
var_dump(filter_var("fe80:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
|
||||
var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE));
|
||||
var_dump(filter_var("5f::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6));
|
||||
@ -26,7 +26,7 @@ string(2) "::"
|
||||
bool(false)
|
||||
string(3) "::1"
|
||||
bool(false)
|
||||
string(10) "fe8:5:6::1"
|
||||
string(11) "fe80:5:6::1"
|
||||
bool(false)
|
||||
string(12) "2001:0db8::1"
|
||||
bool(false)
|
||||
|
14
ext/filter/tests/bug61700.phpt
Normal file
14
ext/filter/tests/bug61700.phpt
Normal file
@ -0,0 +1,14 @@
|
||||
--TEST--
|
||||
Bug #61700 (FILTER_FLAG_IPV6/FILTER_FLAG_NO_PRIV|RES_RANGE failing)
|
||||
--EXTENSIONS--
|
||||
filter
|
||||
--FILE--
|
||||
<?php
|
||||
var_dump(filter_var('::ffff:192.168.1.1', FILTER_VALIDATE_IP, FILTER_FLAG_IPV4));
|
||||
var_dump(filter_var('::ffff:192.168.1.1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE));
|
||||
var_dump(filter_var('0:0:0:0:0:0:0:1', FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE));
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
string(18) "::ffff:192.168.1.1"
|
||||
bool(false)
|
Loading…
Reference in New Issue
Block a user