Abort reference resolution when a reference loop is detected #32
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces logic to track the number of recursive calls to
Token::resolve()
forToken::Ref
objects and uses that state to abort reference resolution with an error when the call depth exceeds 64.Additionally, the PR introduces logic to track any already seen "reference paths" (i.e. fully qualified colon-delimited parameter keys). All reference paths which are found during resolution are checked against the set of seen paths and if a path is already in the set we know that we're trying to resolve a loop where one or more references contain references to each other. In this case, we abort the reference resolution with an error showing the reference paths which form a loop.
The PR introduces a custom struct
ResolveState
to keep track of the call depth and seen reference paths. This design allows us to change the information which is tracked during reference resolution without having to update all call sites.The PR also carefully doesn't track state across boundaries where calls to
Token::resolve()
can't recurse into each other, e.g. for ValueList layers, Sequence elements, and Mapping key-value pairs. See the inline comments for detailed reasoning on why these recursive calls can't recurse into each other.Additionally, the PR adds a number of new tests both for cases which shouldn't be detected as loops and cases which should be detected as loops.
Checklist
bug
,enhancement
,documentation
,change
,breaking
,dependency
,internal
as they show up in the changelog