fix: limit recursive merge aliases - #685
Conversation
eemeli
left a comment
There was a problem hiding this comment.
Calling toJS() for the side effect of applying the anchor node count validation is a bit non-intuitive. Is there potentially a solution in adding a method on ToJSContext where we move the code that's now for that in Alias.toJS(), and call it also from elsewhere?
|
Updated in 5c8bb6e. The alias-count validation now lives in I also added coverage for merge aliases that resolve to sequences so that branch stays exercised directly. Verification:
|
5c8bb6e to
9c27602
Compare
|
The alias-count validation is now centralized in |
eemeli
left a comment
There was a problem hiding this comment.
Hey, finally got back to this. The fix is starting to look pretty good; see inline for a further simplification that ought to be included.
I merged your branch from main to resolve a conflict from merging another PR.
| resolveAlias( | ||
| doc: Document, | ||
| source: Node, | ||
| getAliasCount: () => number |
There was a problem hiding this comment.
There's no need for getAliasCount to get passed around as a callback. Its definition in src/nodes/Alias.ts should be moved here, as this is the only place it's actually called, and its arguments simplified to drop the anchors argument -- it's always this.anchors from here.
|
Moved the alias counting logic into |
| return data.res | ||
| } | ||
|
|
||
| private getAliasCount(doc: Document, node: Node | Pair | null): number { |
There was a problem hiding this comment.
Let's make this actually private.
| private getAliasCount(doc: Document, node: Node | Pair | null): number { | |
| #getAliasCount(doc: Document, node: Node | Pair | null): number { |
| if (!source) { | ||
| const msg = `Unresolved alias (the anchor must be set before the alias): ${value.source}` | ||
| throw new ReferenceError(msg) | ||
| } |
There was a problem hiding this comment.
Sorry, should've caught this earlier: this needs to be tested.
Fixes #677.
This makes cyclic merge aliases fail through the existing alias-count guard instead of recursing until the call stack overflows.
The change keeps an existing anchor entry's count when the same node is re-entered during toJS() conversion, while allowing the resolved JS value to be updated. Merge alias handling now also runs alias toJS() before resolving the merge source, so maxAliasCount is applied to aliases reached through << merge handling.
Verification: