Skip to content

Commit

Permalink
Fix infinite loop of global constants referencing each other
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Sep 29, 2022
1 parent be1ce08 commit 33771e5
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/Analyser/ConstantResolver.php
Expand Up @@ -14,10 +14,12 @@
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ResourceType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use function array_key_exists;
use function in_array;
use const INF;
use const NAN;
Expand All @@ -26,6 +28,9 @@
class ConstantResolver
{

/** @var array<string, true> */
private array $currentlyResolving = [];

/**
* @param string[] $dynamicConstantNames
*/
Expand All @@ -47,10 +52,19 @@ public function resolveConstant(Name $name, ?NamespaceAnswerer $scope): ?Type
return $constantType;
}

if (array_key_exists($resolvedConstantName, $this->currentlyResolving)) {
return new MixedType();
}

$this->currentlyResolving[$resolvedConstantName] = true;

$constantReflection = $this->getReflectionProvider()->getConstant($name, $scope);

This comment has been minimized.

Copy link
@staabm

staabm Sep 29, 2022

Contributor

I think the logic here should be wrapped into a try/finally so the unset($this->currentlyResolving[$resolvedConstantName]); will happen, even if a exception is thrown while reflection

$constantType = $constantReflection->getValueType();

return $this->resolveConstantType($resolvedConstantName, $constantType);
$type = $this->resolveConstantType($resolvedConstantName, $constantType);
unset($this->currentlyResolving[$resolvedConstantName]);

return $type;
}

public function resolvePredefinedConstant(string $resolvedConstantName): ?Type
Expand Down

0 comments on commit 33771e5

Please sign in to comment.