From fac37ba1575a0e8715832e447afe54e045f56fb0 Mon Sep 17 00:00:00 2001 From: Francesco Trotta Date: Fri, 29 Dec 2023 11:15:13 +0100 Subject: [PATCH] fix an edge case with non-enumerable properties --- lib/config/flat-config-schema.js | 2 +- tests/lib/config/flat-config-schema.js | 30 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/config/flat-config-schema.js b/lib/config/flat-config-schema.js index 83c010ea0e3..6b64319c8fc 100644 --- a/lib/config/flat-config-schema.js +++ b/lib/config/flat-config-schema.js @@ -114,7 +114,7 @@ function deepMerge(first, second, mergeMap = new Map()) { for (const key of Object.keys(second)) { // avoid hairy edge case - if (key === "__proto__") { + if (key === "__proto__" || !Object.prototype.propertyIsEnumerable.call(first, key)) { continue; } diff --git a/tests/lib/config/flat-config-schema.js b/tests/lib/config/flat-config-schema.js index ff94d6f910a..b1b7303af62 100644 --- a/tests/lib/config/flat-config-schema.js +++ b/tests/lib/config/flat-config-schema.js @@ -199,6 +199,36 @@ describe("merge", () => { assert.deepStrictEqual(result, { foo: void 0, bar: void 0, baz: void 0 }); }); + it("considers only own enumerable properties", () => { + const first = { + __proto__: { inherited1: "A" }, // non-own properties are not considered + included1: "B", + notMerged1: { first: true } + }; + const second = { + __proto__: { inherited2: "C" }, // non-own properties are not considered + included2: "D", + notMerged2: { second: true } + }; + + // non-enumerable properties are not considered + Object.defineProperty(first, "notMerged2", { enumerable: false, value: { first: true } }); + Object.defineProperty(second, "notMerged1", { enumerable: false, value: { second: true } }); + + const result = merge(first, second); + + assert.deepStrictEqual( + result, + { + included1: "B", + included2: "D", + notMerged1: { first: true }, + notMerged2: { second: true } + } + ); + confirmLegacyMergeResult(first, second, result); + }); + it("merges objects with self-references", () => { const first = { foo: 42 };