Skip to content

Commit

Permalink
Merge pull request #10621 from kkmuffme/fix-numeric-scalar-validate-f…
Browse files Browse the repository at this point in the history
…ilter-var-input
  • Loading branch information
weirdan committed Jan 31, 2024
2 parents abe7ae8 + 7023855 commit 215d62e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
37 changes: 23 additions & 14 deletions src/Psalm/Internal/Provider/ReturnTypeProvider/FilterUtils.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
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;
Expand All @@ -42,6 +43,7 @@
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;
Expand Down Expand Up @@ -919,7 +921,11 @@ public static function getReturnType(
$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();
}

Expand Down Expand Up @@ -967,7 +973,9 @@ public static function getReturnType(
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();
}

Expand All @@ -994,6 +1002,7 @@ public static function getReturnType(
} 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) {
Expand Down Expand Up @@ -1108,7 +1117,9 @@ public static function getReturnType(
$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;
}

Expand All @@ -1129,9 +1140,7 @@ public static function getReturnType(
$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();
}

Expand Down Expand Up @@ -1159,6 +1168,7 @@ public static function getReturnType(
|| $atomic_type instanceof TInt
|| $atomic_type instanceof TFloat
|| $atomic_type instanceof TNumeric
|| $atomic_type instanceof TScalar
|| $atomic_type instanceof TMixed) {
$filter_types[] = new TString();
}
Expand All @@ -1183,11 +1193,10 @@ public static function getReturnType(
} 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;
}

Expand Down Expand Up @@ -1230,7 +1239,7 @@ public static function getReturnType(
continue;
}

if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}

Expand Down Expand Up @@ -1310,7 +1319,7 @@ public static function getReturnType(
continue;
}

if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}

Expand All @@ -1329,7 +1338,7 @@ public static function getReturnType(
continue;
}

if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TString();
}

Expand Down Expand Up @@ -1386,7 +1395,7 @@ public static function getReturnType(
continue;
}

if ($atomic_type instanceof TMixed) {
if ($atomic_type instanceof TMixed || $atomic_type instanceof TScalar) {
$filter_types[] = new TNumericString();
$filter_types[] = Type::getAtomicStringFromLiteral('');
}
Expand Down
18 changes: 18 additions & 0 deletions tests/FunctionCallTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,24 @@ function filterFloat(string $s) : float {
}
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' => [
Expand Down

0 comments on commit 215d62e

Please sign in to comment.