Describe the bug
Converting a YAML document with a cyclic merge alias to native JavaScript may throw a RangeError: Maximum call stack size exceeded, even when maxAliasCount is set.
This appears to affect aliases reached through YAML merge handling, where the usual maxAliasCount handling does not appear to stop recursive merge resolution before stack overflow.
To Reproduce
const { parse } = require('yaml')
parse('&A { <<: *A }', { maxAliasCount: 0, merge: true })
Output
RangeError: Maximum call stack size exceeded
at Object.visit (/poc/node_modules/yaml/dist/visit.js:38:15)
at Alias.resolve (/poc/node_modules/yaml/dist/nodes/Alias.js:30:19)
at Scalar.addMergeToJSMap [as addToJSMap] (/poc/node_modules/yaml/dist/schema/yaml-1.1/merge.js:31:52)
at Object.addPairToJSMap (/poc/node_modules/yaml/dist/nodes/addPairToJSMap.js:11:13)
at YAMLMap.toJSON (/poc/node_modules/yaml/dist/nodes/YAMLMap.js:124:28)
at mergeValue (/poc/node_modules/yaml/dist/schema/yaml-1.1/merge.js:45:27)
at Scalar.addMergeToJSMap [as addToJSMap] (/poc/node_modules/yaml/dist/schema/yaml-1.1/merge.js:39:9)
at Object.addPairToJSMap (/poc/node_modules/yaml/dist/nodes/addPairToJSMap.js:11:13)
at YAMLMap.toJSON (/poc/node_modules/yaml/dist/nodes/YAMLMap.js:124:28)
at mergeValue (/poc/node_modules/yaml/dist/schema/yaml-1.1/merge.js:45:27)
Expected behaviour
I would expect cyclic merge aliases to either be stopped by maxAliasCount, or to fail with a controlled error rather than recursing until stack overflow.
Versions (please complete the following information):
- Node.js v24.15.0
- yaml: reproduced with 2.8.3, 2.0.0, 1.10.3, and 1.5.0
Additional context
This seems related to the existing circular-reference behavior for merge handling. The difference here is that recursive merge resolution is still reached while maxAliasCount is set.
|
test('circular reference', () => { |
|
const src = '&A { <<: *A, B: b }\n' |
|
const doc = parseDocument(src, { merge: true }) |
|
expect(doc.errors).toHaveLength(0) |
|
expect(doc.warnings).toHaveLength(0) |
|
expect(() => doc.toJS()).toThrow('Maximum call stack size exceeded') |
|
expect(String(doc)).toBe(src) |
|
}) |
Describe the bug
Converting a YAML document with a cyclic merge alias to native JavaScript may throw a
RangeError: Maximum call stack size exceeded, even whenmaxAliasCountis set.This appears to affect aliases reached through YAML merge handling, where the usual
maxAliasCounthandling does not appear to stop recursive merge resolution before stack overflow.To Reproduce
Output
Expected behaviour
I would expect cyclic merge aliases to either be stopped by
maxAliasCount, or to fail with a controlled error rather than recursing until stack overflow.Versions (please complete the following information):
Additional context
This seems related to the existing circular-reference behavior for merge handling. The difference here is that recursive merge resolution is still reached while
maxAliasCountis set.yaml/tests/doc/anchors.ts
Lines 458 to 465 in 93c951b