From c41d5f9fe1e9613cf24f6a74e4ba8e9fab7c5733 Mon Sep 17 00:00:00 2001 From: Abdulaziz Ghuloum Date: Wed, 15 Feb 2023 14:18:18 +0300 Subject: [PATCH] handling circular/shared structures in deep-clone (#15366) Co-authored-by: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com> --- .../babel-core/src/transformation/util/clone-deep.ts | 3 ++- packages/babel-core/test/api.js | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/babel-core/src/transformation/util/clone-deep.ts b/packages/babel-core/src/transformation/util/clone-deep.ts index 6d9fc30c302d..d8ae8e7216df 100644 --- a/packages/babel-core/src/transformation/util/clone-deep.ts +++ b/packages/babel-core/src/transformation/util/clone-deep.ts @@ -5,12 +5,14 @@ function deepClone(value: any, cache: Map): any { let cloned: any; if (Array.isArray(value)) { cloned = new Array(value.length); + cache.set(value, cloned); for (let i = 0; i < value.length; i++) { cloned[i] = typeof value[i] !== "object" ? value[i] : deepClone(value[i], cache); } } else { cloned = {}; + cache.set(value, cloned); const keys = Object.keys(value); for (let i = 0; i < keys.length; i++) { const key = keys[i]; @@ -20,7 +22,6 @@ function deepClone(value: any, cache: Map): any { : deepClone(value[key], cache); } } - cache.set(value, cloned); return cloned; } return value; diff --git a/packages/babel-core/test/api.js b/packages/babel-core/test/api.js index dd974edeb5dd..54b8ead5cd30 100644 --- a/packages/babel-core/test/api.js +++ b/packages/babel-core/test/api.js @@ -300,6 +300,16 @@ describe("api", function () { expect(code).toBe(code2); }); + it("transformFromAstSync should not cause infinite recursion with circular objects", () => { + const program = "const identifier = 1"; + const node = parseSync(program); + node.program.body[0].extra = { parent: node.program }; + + expect(transformFromAstSync(node, program, {}).code).toBe( + "const identifier = 1;", + ); + }); + it("transformFromAst should not mutate the AST", function () { const program = "const identifier = 1"; const node = parseSync(program);