Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 39e2474

Browse filesBrowse files
TrottMyles Borins
authored andcommitted
assert: allow circular references
assert.deepEqual() and assert.deepStrictEqual() will no longer throw a RangeError if passed objects with circular references. PR-URL: #6432 Fixes: #6416 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 5380743 commit 39e2474
Copy full SHA for 39e2474

File tree

Expand file treeCollapse file tree

2 files changed

+37
-16
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+37
-16
lines changed
Open diff view settings
Collapse file

‎lib/assert.js‎

Copy file name to clipboardExpand all lines: lib/assert.js
+17-4Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
143143
}
144144
};
145145

146-
function _deepEqual(actual, expected, strict) {
146+
function _deepEqual(actual, expected, strict, memos) {
147147
// 7.1. All identical values are equivalent, as determined by ===.
148148
if (actual === expected) {
149149
return true;
@@ -191,15 +191,27 @@ function _deepEqual(actual, expected, strict) {
191191
// corresponding key, and an identical 'prototype' property. Note: this
192192
// accounts for both named and indexed properties on Arrays.
193193
} else {
194-
return objEquiv(actual, expected, strict);
194+
memos = memos || {actual: [], expected: []};
195+
196+
const actualIndex = memos.actual.indexOf(actual);
197+
if (actualIndex !== -1) {
198+
if (actualIndex === memos.expected.indexOf(expected)) {
199+
return true;
200+
}
201+
}
202+
203+
memos.actual.push(actual);
204+
memos.expected.push(expected);
205+
206+
return objEquiv(actual, expected, strict, memos);
195207
}
196208
}
197209

198210
function isArguments(object) {
199211
return Object.prototype.toString.call(object) == '[object Arguments]';
200212
}
201213

202-
function objEquiv(a, b, strict) {
214+
function objEquiv(a, b, strict, actualVisitedObjects) {
203215
if (a === null || a === undefined || b === null || b === undefined)
204216
return false;
205217
// if one is a primitive, the other must be same
@@ -235,7 +247,8 @@ function objEquiv(a, b, strict) {
235247
//~~~possibly expensive deep test
236248
for (i = ka.length - 1; i >= 0; i--) {
237249
key = ka[i];
238-
if (!_deepEqual(a[key], b[key], strict)) return false;
250+
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
251+
return false;
239252
}
240253
return true;
241254
}
Collapse file

‎test/parallel/test-assert.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-assert.js
+20-12Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -380,25 +380,33 @@ try {
380380

381381
assert.ok(threw);
382382

383-
// GH-207. Make sure deepEqual doesn't loop forever on circular refs
384-
var b = {};
385-
b.b = b;
383+
// https://github.com/nodejs/node/issues/6416
384+
// Make sure circular refs don't throw.
385+
{
386+
const b = {};
387+
b.b = b;
386388

387-
var c = {};
388-
c.b = c;
389+
const c = {};
390+
c.b = c;
389391

390-
var gotError = false;
391-
try {
392-
assert.deepEqual(b, c);
393-
} catch (e) {
394-
gotError = true;
395-
}
392+
a.doesNotThrow(makeBlock(a.deepEqual, b, c));
393+
a.doesNotThrow(makeBlock(a.deepStrictEqual, b, c));
396394

395+
const d = {};
396+
d.a = 1;
397+
d.b = d;
398+
399+
const e = {};
400+
e.a = 1;
401+
e.b = e.a;
402+
403+
a.throws(makeBlock(a.deepEqual, d, e), /AssertionError/);
404+
a.throws(makeBlock(a.deepStrictEqual, d, e), /AssertionError/);
405+
}
397406
// GH-7178. Ensure reflexivity of deepEqual with `arguments` objects.
398407
var args = (function() { return arguments; })();
399408
a.throws(makeBlock(a.deepEqual, [], args));
400409
a.throws(makeBlock(a.deepEqual, args, []));
401-
assert.ok(gotError);
402410

403411

404412
var circular = {y: 1};

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.