1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #10621 from kkmuffme/fix-numeric-scalar-validate-filter-var-input

This commit is contained in:
Bruce Weirdan 2024-01-31 14:28:25 -04:00 committed by GitHub
commit 215d62eb72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 14 deletions

View File

@ -33,6 +33,7 @@ use Psalm\Type\Atomic\TNonFalsyString;
use Psalm\Type\Atomic\TNull;
use Psalm\Type\Atomic\TNumeric;
use Psalm\Type\Atomic\TNumericString;
use Psalm\Type\Atomic\TScalar;
use Psalm\Type\Atomic\TString;
use Psalm\Type\Atomic\TTrue;
use Psalm\Type\Union;
@ -42,6 +43,7 @@ use function array_diff;
use function array_keys;
use function array_merge;
use function filter_var;
use function get_class;
use function implode;
use function in_array;
use function preg_match;
@ -919,7 +921,11 @@ final class FilterUtils
$filter_types[] = new TFloat();
}
if ($atomic_type instanceof TMixed) {
// only these specific classes, not any class that extends either
// to avoid matching already better handled cases from above, e.g. float is numeric and scalar
if ($atomic_type instanceof TMixed
|| get_class($atomic_type) === TNumeric::class
|| get_class($atomic_type) === TScalar::class) {
$filter_types[] = new TFloat();
}
@ -967,7 +973,9 @@ final class FilterUtils
if ($atomic_type instanceof TMixed
|| $atomic_type instanceof TString
|| $atomic_type instanceof TInt
|| $atomic_type instanceof TFloat) {
|| $atomic_type instanceof TFloat
|| $atomic_type instanceof TNumeric
|| $atomic_type instanceof TScalar) {
$filter_types[] = new TBool();
}
@ -994,6 +1002,7 @@ final class FilterUtils
} else {
$int_type = new TInt();
}
foreach ($input_type->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof TLiteralInt) {
if ($min_range !== null && $min_range > $atomic_type->value) {
@ -1108,7 +1117,9 @@ final class FilterUtils
$filter_types[] = $int_type;
}
if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed
|| get_class($atomic_type) === TNumeric::class
|| get_class($atomic_type) === TScalar::class) {
$filter_types[] = $int_type;
}
@ -1129,9 +1140,7 @@ final class FilterUtils
$filter_types[] = $atomic_type;
} elseif ($atomic_type instanceof TString) {
$filter_types[] = new TNonFalsyString();
}
if ($atomic_type instanceof TMixed) {
} elseif ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TNonFalsyString();
}
@ -1159,6 +1168,7 @@ final class FilterUtils
|| $atomic_type instanceof TInt
|| $atomic_type instanceof TFloat
|| $atomic_type instanceof TNumeric
|| $atomic_type instanceof TScalar
|| $atomic_type instanceof TMixed) {
$filter_types[] = new TString();
}
@ -1183,11 +1193,10 @@ final class FilterUtils
} else {
$filter_types[] = $atomic_type;
}
}
if ($atomic_type instanceof TMixed
} elseif ($atomic_type instanceof TMixed
|| $atomic_type instanceof TInt
|| $atomic_type instanceof TFloat) {
|| $atomic_type instanceof TFloat
|| $atomic_type instanceof TScalar) {
$filter_types[] = $string_type;
}
@ -1230,7 +1239,7 @@ final class FilterUtils
continue;
}
if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}
@ -1310,7 +1319,7 @@ final class FilterUtils
continue;
}
if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}
@ -1329,7 +1338,7 @@ final class FilterUtils
continue;
}
if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}
@ -1386,7 +1395,7 @@ final class FilterUtils
continue;
}
if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TNumericString();
$filter_types[] = Type::getAtomicStringFromLiteral('');
}

View File

@ -1118,6 +1118,24 @@ class FunctionCallTest extends TestCase
}
function filterFloatWithDefault(string $s) : float {
return filter_var($s, FILTER_VALIDATE_FLOAT, ["options" => ["default" => 5.0]]);
}
/**
* @param mixed $c
* @return int<1, 100>|stdClass|array<never, never>
*/
function filterNumericIntWithDefault($c) {
if (is_numeric($c)) {
return filter_var($c, FILTER_VALIDATE_INT, [
"options" => [
"default" => new stdClass(),
"min_range" => 1,
"max_range" => 100,
],
]);
}
return array();
}',
],
'callVariableVar' => [