Browse Source
Code review:
Code review:
. fixed integer overflow . fixed buffer overflow/underflow . added more strict IP validation . reimplemented float number validationexperimental/5.2-WITH_DRCP
12 changed files with 501 additions and 403 deletions
-
33ext/filter/filter.c
-
28ext/filter/filter_private.h
-
620ext/filter/logical_filters.c
-
8ext/filter/tests/030.phpt
-
30ext/filter/tests/045.phpt
-
23ext/filter/tests/046.phpt
-
37ext/filter/tests/047.phpt
-
41ext/filter/tests/048.phpt
-
34ext/filter/tests/049.phpt
-
29ext/filter/tests/050.phpt
-
11ext/filter/tests/051.phpt
-
10ext/filter/tests/bug7733.phpt
@ -0,0 +1,30 @@ |
|||||
|
--TEST-- |
||||
|
Options must not be changed by filter_var() |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
$a = array("flags"=>(string)FILTER_FLAG_ALLOW_HEX, "options" => array("min_range"=>"0", "max_range"=>"1024")); |
||||
|
$ret = filter_var("0xff", FILTER_VALIDATE_INT, $a); |
||||
|
echo ($ret === 255 && $a["options"]["min_range"] === "0")?"ok\n":"bug\n"; |
||||
|
echo ($ret === 255 && $a["options"]["max_range"] === "1024")?"ok\n":"bug\n"; |
||||
|
echo ($ret === 255 && is_string($a["flags"]) && $a["flags"] == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; |
||||
|
$a = (string)FILTER_FLAG_ALLOW_HEX; |
||||
|
$ret = filter_var("0xff", FILTER_VALIDATE_INT, $a); |
||||
|
echo ($ret === 255 && is_string($a) && $a == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; |
||||
|
$a = array("test"=>array("filter"=>(string)FILTER_VALIDATE_INT, "flags"=>(string)FILTER_FLAG_ALLOW_HEX)); |
||||
|
$ret = filter_var_array(array("test"=>"0xff"), $a); |
||||
|
echo ($ret["test"] === 255 && is_string($a["test"]["filter"]) && $a["test"]["filter"] == FILTER_VALIDATE_INT)?"ok\n":"bug\n"; |
||||
|
echo ($ret["test"] === 255 && is_string($a["test"]["flags"]) && $a["test"]["flags"] == FILTER_FLAG_ALLOW_HEX)?"ok\n":"bug\n"; |
||||
|
$a = array("test"=>(string)FILTER_VALIDATE_INT); |
||||
|
$ret = filter_var_array(array("test"=>"255"), $a); |
||||
|
echo ($ret["test"] === 255 && is_string($a["test"]) && $a["test"] == FILTER_VALIDATE_INT)?"ok\n":"bug\n"; |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
ok |
||||
|
ok |
||||
|
ok |
||||
|
ok |
||||
|
ok |
||||
|
ok |
||||
|
ok |
||||
@ -0,0 +1,23 @@ |
|||||
|
--TEST-- |
||||
|
Integer overflow |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
$s = sprintf("%d", PHP_INT_MAX); |
||||
|
var_dump(is_long(filter_var($s, FILTER_VALIDATE_INT))); |
||||
|
|
||||
|
$s = sprintf("%.0f", PHP_INT_MAX+1); |
||||
|
var_dump(filter_var($s, FILTER_VALIDATE_INT)); |
||||
|
|
||||
|
$s = sprintf("%d", -PHP_INT_MAX); |
||||
|
var_dump(is_long(filter_var($s, FILTER_VALIDATE_INT))); |
||||
|
|
||||
|
$s = sprintf("%.0f", -(PHP_INT_MAX+1)); |
||||
|
var_dump(filter_var($s, FILTER_VALIDATE_INT)); |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
bool(true) |
||||
|
bool(false) |
||||
|
bool(true) |
||||
|
bool(false) |
||||
@ -0,0 +1,37 @@ |
|||||
|
--TEST-- |
||||
|
Octal integer overflow |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
function octal_inc($s) { |
||||
|
$len = strlen($s); |
||||
|
while ($len > 0) { |
||||
|
$len--; |
||||
|
if ($s[$len] != '7') { |
||||
|
$s[$len] = $s[$len] + 1; |
||||
|
return $s; |
||||
|
} |
||||
|
$s[$len] = '0'; |
||||
|
} |
||||
|
return '1'.$s; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
$s = sprintf("%o", PHP_INT_MAX); |
||||
|
var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); |
||||
|
|
||||
|
$s = octal_inc($s); |
||||
|
var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); |
||||
|
|
||||
|
$s = sprintf("%o", ~0); |
||||
|
var_dump(is_long(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL)))); |
||||
|
|
||||
|
$s = octal_inc($s); |
||||
|
var_dump(filter_var('0'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_OCTAL))); |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
bool(true) |
||||
|
bool(true) |
||||
|
bool(true) |
||||
|
bool(false) |
||||
@ -0,0 +1,41 @@ |
|||||
|
--TEST-- |
||||
|
Hex integer overflow |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
function hex_inc($s) { |
||||
|
$len = strlen($s); |
||||
|
while ($len > 0) { |
||||
|
$len--; |
||||
|
if ($s[$len] != 'f') { |
||||
|
if ($s[$len] == '9') { |
||||
|
$s[$len] = 'a'; |
||||
|
} else { |
||||
|
$s[$len] = $s[$len] + 1; |
||||
|
} |
||||
|
return $s; |
||||
|
} |
||||
|
$s[$len] = '0'; |
||||
|
} |
||||
|
return '1'.$s; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
$s = sprintf("%x", PHP_INT_MAX); |
||||
|
var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); |
||||
|
|
||||
|
$s = hex_inc($s); |
||||
|
var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); |
||||
|
|
||||
|
$s = sprintf("%x", ~0); |
||||
|
var_dump(is_long(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX)))); |
||||
|
|
||||
|
$s = hex_inc($s); |
||||
|
var_dump(filter_var('0x'.$s, FILTER_VALIDATE_INT, array("flags"=>FILTER_FLAG_ALLOW_HEX))); |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
bool(true) |
||||
|
bool(true) |
||||
|
bool(true) |
||||
|
bool(false) |
||||
@ -0,0 +1,34 @@ |
|||||
|
--TEST-- |
||||
|
filter_var() and doubles with thousend separators |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
$test = array( |
||||
|
'0' => 0.0, |
||||
|
'12345678900.1234567165' => 12345678900.1234567165, |
||||
|
'1,234,567,890.1234567165' => 1234567890.1234567165, |
||||
|
'-1,234,567,890.1234567165' => -1234567890.1234567165, |
||||
|
'1234,567,890.1234567165' => false, |
||||
|
'1,234,567,89.1234567165' => false, |
||||
|
'1,234,567,8900.1234567165' => false, |
||||
|
'1.234.567.890.1234567165' => false, |
||||
|
'1,234,567,8900.123,456' => false, |
||||
|
); |
||||
|
foreach ($test as $src => $dst) { |
||||
|
$out = filter_var($src, FILTER_VALIDATE_FLOAT, array("flags"=>FILTER_FLAG_ALLOW_THOUSAND)); |
||||
|
if ($dst !== $out) { |
||||
|
if ($out === false) { |
||||
|
echo "$src -> false != $dst\n"; |
||||
|
} elseif ($dst === false) { |
||||
|
echo "$src -> $out != false\n"; |
||||
|
} else { |
||||
|
echo "$src -> $out != $dst\n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
echo "Ok\n"; |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
Ok |
||||
@ -0,0 +1,29 @@ |
|||||
|
--TEST-- |
||||
|
filter_var() and double overflow/underflow |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
$test = array( |
||||
|
'1e+308' => 1e+308, |
||||
|
'1e+309' => false, |
||||
|
'1e-323' => 1e-323, |
||||
|
'1e-324' => false, |
||||
|
); |
||||
|
foreach ($test as $src => $dst) { |
||||
|
$out = filter_var($src, FILTER_VALIDATE_FLOAT); |
||||
|
if ($dst !== $out) { |
||||
|
if ($out === false) { |
||||
|
echo "$src -> false != $dst\n"; |
||||
|
} elseif ($dst === false) { |
||||
|
echo "$src -> $out != false\n"; |
||||
|
} else { |
||||
|
echo "$src -> $out != $dst\n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
echo "Ok\n"; |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
Ok |
||||
@ -0,0 +1,11 @@ |
|||||
|
--TEST-- |
||||
|
filter_var() and default values |
||||
|
--SKIPIF-- |
||||
|
<?php if (!extension_loaded("filter")) die("skip"); ?> |
||||
|
--FILE-- |
||||
|
<?php |
||||
|
$tmp = $default = 321; |
||||
|
var_dump(filter_var("123asd", FILTER_VALIDATE_INT, array("options"=>array("default"=>$default)))); |
||||
|
?> |
||||
|
--EXPECT-- |
||||
|
int(321) |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue