Skip to content

Commit 0883ece

Browse files
committed
Support compound types as filter_input type constant
1 parent 35cf323 commit 0883ece

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

src/Type/Php/FilterInputDynamicReturnTypeExtension.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@
22

33
namespace PHPStan\Type\Php;
44

5-
use PhpParser\Node\Expr\ConstFetch;
5+
use PhpParser\Node;
66
use PhpParser\Node\Expr\FuncCall;
77
use PHPStan\Analyser\Scope;
88
use PHPStan\Reflection\FunctionReflection;
9+
use PHPStan\Reflection\ReflectionProvider;
910
use PHPStan\Type\ArrayType;
1011
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
1112
use PHPStan\Type\MixedType;
1213
use PHPStan\Type\StringType;
1314
use PHPStan\Type\Type;
15+
use PHPStan\Type\TypeCombinator;
1416
use function count;
15-
use function in_array;
1617

1718
class FilterInputDynamicReturnTypeExtension implements DynamicFunctionReturnTypeExtension
1819
{
1920

20-
public function __construct(private FilterFunctionReturnTypeHelper $filterFunctionReturnTypeHelper)
21+
public function __construct(private FilterFunctionReturnTypeHelper $filterFunctionReturnTypeHelper, private ReflectionProvider $reflectionProvider)
2122
{
2223
}
2324

@@ -32,11 +33,15 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
3233
return null;
3334
}
3435

35-
$typeExpr = $functionCall->getArgs()[0]->value;
36-
if (
37-
!($typeExpr instanceof ConstFetch)
38-
|| !in_array((string) $typeExpr->name, ['INPUT_GET', 'INPUT_POST', 'INPUT_COOKIE', 'INPUT_SERVER', 'INPUT_ENV'], true)
39-
) {
36+
$supportedTypes = TypeCombinator::union(
37+
$this->reflectionProvider->getConstant(new Node\Name('INPUT_GET'), null)->getValueType(),
38+
$this->reflectionProvider->getConstant(new Node\Name('INPUT_POST'), null)->getValueType(),
39+
$this->reflectionProvider->getConstant(new Node\Name('INPUT_COOKIE'), null)->getValueType(),
40+
$this->reflectionProvider->getConstant(new Node\Name('INPUT_SERVER'), null)->getValueType(),
41+
$this->reflectionProvider->getConstant(new Node\Name('INPUT_ENV'), null)->getValueType(),
42+
);
43+
$typeType = $scope->getType($functionCall->getArgs()[0]->value);
44+
if (!$typeType->isInteger()->yes() || $supportedTypes->isSuperTypeOf($typeType)->no()) {
4045
return null;
4146
}
4247

tests/PHPStan/Analyser/data/filter-input.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ public function supportedSuperGlobals(): void
2424
assertType('int|false|null', filter_input(INPUT_ENV, 'foo', FILTER_VALIDATE_INT));
2525
}
2626

27+
public function inputTypeUnion(): void
28+
{
29+
assertType('int|false|null', filter_input(rand(0, 1) ? INPUT_GET : INPUT_POST, 'foo', FILTER_VALIDATE_INT));
30+
}
31+
2732
public function doFoo(string $foo): void
2833
{
2934
assertType('int|false|null', filter_input(INPUT_GET, $foo, FILTER_VALIDATE_INT));

0 commit comments

Comments
 (0)