mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
assert,util: fix stale nested cycle memo entries
Temporary nested cycle-tracking entries could remain in the memory set after a successful comparison. If a later sibling comparison reused one of those objects, deepStrictEqual could incorrectly fail for equivalent structures. This cleans up the temporary nested entries after the nested comparison returns. Fixes: https://github.com/nodejs/node/issues/62422 PR-URL: https://github.com/nodejs/node/pull/62509 Fixes: https://github.com/nodejs/node/issues/62422 Reviewed-By: Jordan Harband <ljharb@gmail.com>
This commit is contained in:
1 parent
b52102f11d
commit
8db9d43c45
2 files changed
+42
No files matched your search
@@ -529,6 +529,10 @@ function handleCycles(val1, val2, mode, keys1, keys2, memos, iterationType) {
|
||||
memos.deep = true;
|
||||
const result = objEquiv(val1, val2, mode, keys1, keys2, memos, iterationType);
|
||||
memos.deep = false;
|
||||
if (memos.set !== undefined) {
|
||||
memos.set.delete(memos.c);
|
||||
memos.set.delete(memos.d);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
memos.set = new SafeSet();
|
||||
|
||||
@@ -260,6 +260,14 @@ function assertOnlyDeepEqual(a, b, err) {
|
||||
assert.throws(partial, err || { code: 'ERR_ASSERTION' });
|
||||
}
|
||||
|
||||
function activateMemoizedCycleDetection() {
|
||||
const circA = {};
|
||||
circA.self = circA;
|
||||
const circB = {};
|
||||
circB.self = circB;
|
||||
assert.deepStrictEqual(circA, circB);
|
||||
}
|
||||
|
||||
test('es6 Maps and Sets', () => {
|
||||
assertDeepAndStrictEqual(new Set(), new Set());
|
||||
assertDeepAndStrictEqual(new Map(), new Map());
|
||||
@@ -609,6 +617,36 @@ test('GH-14441. Circular structures should be consistent', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('deepStrictEqual handles shared expected array elements after cycle detection', () => {
|
||||
const sharedExpected = { outer: { inner: 0 } };
|
||||
const actualValues = [{ outer: { inner: 0 } }, { outer: { inner: 0 } }];
|
||||
const expectedValues = [sharedExpected, sharedExpected];
|
||||
|
||||
activateMemoizedCycleDetection();
|
||||
|
||||
assertDeepAndStrictEqual(actualValues[0], expectedValues[0]);
|
||||
assertDeepAndStrictEqual(actualValues[1], expectedValues[1]);
|
||||
assertDeepAndStrictEqual(actualValues, expectedValues);
|
||||
});
|
||||
|
||||
test('deepStrictEqual handles cross-root aliases after cycle detection', () => {
|
||||
activateMemoizedCycleDetection();
|
||||
|
||||
const nestedExpected = {};
|
||||
nestedExpected.loop = nestedExpected;
|
||||
nestedExpected.payload = { value: 1 };
|
||||
|
||||
const expected = {};
|
||||
expected.loop = nestedExpected;
|
||||
expected.payload = { value: 1 };
|
||||
|
||||
const actual = {};
|
||||
actual.loop = expected;
|
||||
actual.payload = { value: 1 };
|
||||
|
||||
assertDeepAndStrictEqual(actual, expected);
|
||||
});
|
||||
|
||||
// https://github.com/nodejs/node-v0.x-archive/pull/7178
|
||||
test('Ensure reflexivity of deepEqual with `arguments` objects.', () => {
|
||||
const args = (function() { return arguments; })();
|
||||
|
||||
Reference in new issue
Block a user