Skip to content

Commit

Permalink
handling circular/shared structures in deep-clone (#15366)
Browse files Browse the repository at this point in the history
Co-authored-by: liuxingbaoyu <30521560+liuxingbaoyu@users.noreply.github.com>
  • Loading branch information
azizghuloum and liuxingbaoyu committed Feb 15, 2023
1 parent eb4dfe7 commit c41d5f9
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/babel-core/src/transformation/util/clone-deep.ts
Expand Up @@ -5,12 +5,14 @@ function deepClone(value: any, cache: Map<any, any>): 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];
Expand All @@ -20,7 +22,6 @@ function deepClone(value: any, cache: Map<any, any>): any {
: deepClone(value[key], cache);
}
}
cache.set(value, cloned);
return cloned;
}
return value;
Expand Down
10 changes: 10 additions & 0 deletions packages/babel-core/test/api.js
Expand Up @@ -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);
Expand Down

0 comments on commit c41d5f9

Please sign in to comment.