diff --git a/packages/@aws-cdk/aws-stepfunctions/lib/json-path.ts b/packages/@aws-cdk/aws-stepfunctions/lib/json-path.ts index b172ed94de411..7a4a56c536a6b 100644 --- a/packages/@aws-cdk/aws-stepfunctions/lib/json-path.ts +++ b/packages/@aws-cdk/aws-stepfunctions/lib/json-path.ts @@ -83,11 +83,12 @@ interface FieldHandlers { export function recurseObject(obj: object | undefined, handlers: FieldHandlers, visited: object[] = []): object | undefined { if (obj === undefined) { return undefined; } - if (visited.includes(obj)) { - return {}; - } else { - visited.push(obj); - } + + // Avoiding infinite recursion + if (visited.includes(obj)) { return {}; } + + // Marking current object as visited for the current recursion path + visited.push(obj); const ret: any = {}; for (const [key, value] of Object.entries(obj)) { @@ -106,6 +107,10 @@ export function recurseObject(obj: object | undefined, handlers: FieldHandlers, } } + // Removing from visited after leaving the current recursion path + // Allowing it to be visited again if it's not causing a recursion (circular reference) + visited.pop(); + return ret; } diff --git a/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts b/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts index b9ff82b175709..15591ddeebd76 100644 --- a/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts +++ b/packages/@aws-cdk/aws-stepfunctions/test/fields.test.ts @@ -152,4 +152,26 @@ describe('Fields', () => { expect(FieldUtils.findReferencedPaths(paths)) .toStrictEqual(['$.listField', '$.numField', '$.stringField']); }); + + test('repeated object references at different tree paths should not be considered as recursions', () => { + const repeatedObject = { + field: JsonPath.stringAt('$.stringField'), + numField: JsonPath.numberAt('$.numField'), + }; + expect(FieldUtils.renderObject( + { + reference1: repeatedObject, + reference2: repeatedObject, + }, + )).toStrictEqual({ + reference1: { + 'field.$': '$.stringField', + 'numField.$': '$.numField', + }, + reference2: { + 'field.$': '$.stringField', + 'numField.$': '$.numField', + }, + }); + }); });