From c7d25c7b4463d838f6dbc53b8b5d30b01fbf0adf Mon Sep 17 00:00:00 2001 From: Dylan McGannon Date: Sun, 11 Nov 2018 14:26:39 +1100 Subject: [PATCH] fix(definitionresolver): infinite loop when indexing self referencing classes (#670) --- fixtures/self_referencing_class.php | 20 ++++++++++++++++++++ src/DefinitionResolver.php | 8 +++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 fixtures/self_referencing_class.php diff --git a/fixtures/self_referencing_class.php b/fixtures/self_referencing_class.php new file mode 100644 index 0000000..06dc8f0 --- /dev/null +++ b/fixtures/self_referencing_class.php @@ -0,0 +1,20 @@ +undef_prop = 1; + +$b = new B; +$b->undef_prop = 1; + +$d = new D; +$d->undef_prop = 1; diff --git a/src/DefinitionResolver.php b/src/DefinitionResolver.php index f3d6fa1..adddf77 100644 --- a/src/DefinitionResolver.php +++ b/src/DefinitionResolver.php @@ -438,6 +438,7 @@ class DefinitionResolver // Find the right class that implements the member $implementorFqns = [$classFqn]; + $visitedFqns = []; while ($implementorFqn = array_shift($implementorFqns)) { // If the member FQN exists, return it @@ -450,10 +451,15 @@ class DefinitionResolver if ($implementorDef === null) { break; } + // Note the FQN as visited + $visitedFqns[] = $implementorFqn; // Repeat for parent class if ($implementorDef->extends) { foreach ($implementorDef->extends as $extends) { - $implementorFqns[] = $extends; + // Don't add the parent FQN if it's already been visited + if (!\in_array($extends, $visitedFqns)) { + $implementorFqns[] = $extends; + } } } }