- Fixed the filter extension accepting IPv4 octets with a leading 0 as that

belongs to the unsupported "dotted octal" representation.
- Fixed bug #53236 (problems in the validation of IPv6 addresses with leading
  and trailing :: in the filter extension).
- Fixed bug #50117 (problems in the validation of IPv6 addresses with IPv4
  addresses and ::).
This commit is contained in:
Gustavo André dos Santos Lopes 2010-11-08 04:36:15 +00:00
parent f407fc4e01
commit c3557ba32e
3 changed files with 73 additions and 30 deletions

6
NEWS
View File

@ -52,11 +52,15 @@
- Fixed ReflectionProperty::isDefault() giving a wrong result for properties
obtained with ReflectionClass::getProperties(). (Gustavo)
- Fixed covariance of return-by-ref constraints. (Etienne)
- Fixed the filter extension accepting IPv4 octets with a leading 0 as that
belongs to the unsupported "dotted octal" representation. (Gustavo)
- Fixed bug #53248 (rawurlencode RFC 3986 EBCDIC support misses tilde char).
(Justin Martin)
- Fixed bug #53241 (stream casting that relies on fdopen/fopencookie fails
with streams opened with, inter alia, the 'xb' mode). (Gustavo)
- Fixed bug #53236 (problems in the validation of IPv6 addresses with leading
and trailing :: in the filter extension). (Gustavo)
- Fixed bug #53226 (file_exists fails on big filenames). (Adam)
- Fixed bug #53198 (changing INI setting "from" with ini_set did not have any
effect). (Gustavo)
@ -177,6 +181,8 @@
other platforms). (Pierre)
- Fixed bug #50345 (nanosleep not detected properly on some solaris versions).
(Ulf, Tony)
- Fixed bug #50117 (problems in the validation of IPv6 addresses with IPv4
addresses and ::). (Gustavo)
- Fixed bug #49687 (utf8_decode vulnerabilities and deficiencies in the number
of reported malformed sequences). (CVE-2010-3870) (Gustavo)
- Fixed bug #49407 (get_html_translation_table doesn't handle UTF-8). (Gustavo)

View File

@ -557,9 +557,11 @@ static int _php_filter_validate_ipv4(char *str, int str_len, int *ip) /* {{{ */
int n = 0;
while (str < end) {
int leading_zero;
if (*str < '0' || *str > '9') {
return 0;
}
leading_zero = (*str == '0');
m = 1;
num = ((*(str++)) - '0');
while (str < end && (*str >= '0' && *str <= '9')) {
@ -568,6 +570,10 @@ static int _php_filter_validate_ipv4(char *str, int str_len, int *ip) /* {{{ */
return 0;
}
}
/* don't allow a leading 0; that introduces octal numbers,
* which we don't support */
if (leading_zero && (num != 0 || m > 1))
return 0;
ip[n++] = num;
if (n == 4) {
return str == end;
@ -582,7 +588,7 @@ static int _php_filter_validate_ipv4(char *str, int str_len, int *ip) /* {{{ */
static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */
{
int compressed = 0;
int blocks = 8;
int blocks = 0;
int n;
char *ipv4;
char *end;
@ -603,32 +609,40 @@ static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */
if (!_php_filter_validate_ipv4(ipv4, (str_len - (ipv4 - str)), ip4elm)) {
return 0;
}
str_len = (ipv4 - str) - 1;
if (str_len == 1) {
return *str == ':';
str_len = ipv4 - str; /* length excluding ipv4 */
if (str_len < 2) {
return 0;
}
blocks = 6;
if (ipv4[-2] != ':') {
/* don't include : before ipv4 unless it's a :: */
str_len--;
}
blocks = 2;
}
end = str + str_len;
while (str < end) {
if (*str == ':') {
if (--blocks == 0) {
return 0;
}
if (++str >= end) {
/* cannot end in : without previous : */
return 0;
}
if (*str == ':') {
if (compressed || --blocks == 0) {
if (compressed) {
return 0;
}
if (++str == end) {
return 1;
}
blocks++; /* :: means 1 or more 16-bit 0 blocks */
compressed = 1;
if (++str == end) {
return (blocks <= 8);
}
} else if ((str - 1) == s) {
/* dont allow leading : without another : following */
return 0;
}
}
@ -643,8 +657,10 @@ static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */
if (n < 1 || n > 4) {
return 0;
}
if (++blocks > 8)
return 0;
}
return (compressed || blocks == 1);
return ((compressed && blocks <= 8) || blocks == 8);
}
/* }}} */

View File

@ -5,35 +5,56 @@ filter_var() and IPv6
--FILE--
<?php
$ipv6_test = array(
"::127.0.0.1" => true,
"FF01::101:127.0.1" => false,
"FF01:0:0:0:101:127.0.1.1" => false,
"FF01:0:0:0:237:101:127.0.1.1" => true,
"FF01::101" => true,
"A1080::8:800:200C:417A" => false,
"1080::8:Z00:200C:417A" => false,
"FF01::101::1" => false,
"1080::8:800:200C:417A" => true,
"1080:0:0:0:8:800:200C:417A" => true,
"::127.0.0.1" => true,
"FF01::101:127.0.1" => false,
"FF01:0:0:0:101:127.0.1.1" => false,
"FF01:0:0:0:237:101:127.0.1.1" => true,
"FF01::101" => true,
"A1080::8:800:200C:417A" => false,
"1080::8:Z00:200C:417A" => false,
"FF01::101::1" => false,
"1080::8:800:200C:417A" => true,
"1080:0:0:0:8:800:200C:417A" => true,
"2001:ec8:1:1:1:1:1:1" => true,
"ffff::FFFF:129.144.52.38" => true,
"::ffff:1.2.3.4" => true,
"0:0:0:0:0:FFFF:129.144.52.38" => true,
"0:0:0:0:0:0:13.1.68.3" => true,
"::13.1.68.3" => true,
"::FFFF:129.144.52.38" => true,
"0:0:0:0:0:FFFF:129.144.52.38" => true,
"0:0:0:0:0:0:13.1.68.3" => true,
"0:0:0:0:0:0:0:13.1.68.3" => false,
"::13.1.68.3" => true,
"::FFFF:129.144.52.38" => true,
"1:2:3:4:5:6::129.144.52.38" => false,
"::1:2:3:4:5:6:129.144.52.38" => false,
"1:2:3::4:5:6:129.144.52.38" => false,
"1:2:3:4:5:6:7:8::" => false,
"::1:2:3:4:5:6:7:8" => false,
"1:2:3:4::5:6:7:8" => false,
"::1:2:3:4:5:6:7" => true,
"::1:2:3:4:5:6:7:8" => false,
"1:2:3:4:5:6:7::" => true,
"1:2:3:4:5:6:7:8::" => false,
"1:2:3:4:5:6:7::8" => false,
"1:2:3:4:5:6:7:8g" => false,
"1:2:3:4:5:6:7:g" => false,
"1:2:3:4:5g:6:7:8" => false,
'a:b:c:d:e::1.2.3.4' => true,
'::0:a:b:c:d:e:f' => true,
'0:a:b:c:d:e:f::' => true,
':::1.2.3.4' => false,
'8:::1.2.3.4' => false,
'::01.02.03.04' => false,
'::1.00.3.4' => false,
'0:0:0:255.255.255.255' => false,
'0:0:0::255.255.255.255' => true,
);
foreach ($ipv6_test as $ip => $exp) {
$out = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6);
$out = (int) ($out === false ? 0 : 1);
if ($exp != $out) {
echo "$ip failed\n";
echo "$ip failed (expected ", $exp?"true":"false", ", got ",
$out?"true":"false", ")\n";
}
}