Skip to content

Commit

Permalink
console,util: fix missing recursion end while inspecting prototypes
Browse files Browse the repository at this point in the history
This makes sure prototypes won't be inspected infinitely for some
obscure object creations. The depth is now taken into account and
the recursion ends when the depth limit is reached.

PR-URL: #29647
Fixes: #29646
Reviewed-By: Jeremiah Senkpiel <[email protected]>
Reviewed-By: Minwoo Jung <[email protected]>
  • Loading branch information
BridgeAR authored and Trott committed Sep 24, 2019
1 parent 0c32ca9 commit 1fa4037
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
25 changes: 19 additions & 6 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ function getEmptyFormatArray() {
return [];
}

function getConstructorName(obj, ctx) {
function getConstructorName(obj, ctx, recurseTimes) {
let firstProto;
const tmp = obj;
while (obj) {
Expand All @@ -372,10 +372,23 @@ function getConstructorName(obj, ctx) {
return null;
}

return `${internalGetConstructorName(tmp)} <${inspect(firstProto, {
...ctx,
customInspect: false
})}>`;
const res = internalGetConstructorName(tmp);

if (recurseTimes > ctx.depth && ctx.depth !== null) {
return `${res} <Complex prototype>`;
}

const protoConstr = getConstructorName(firstProto, ctx, recurseTimes + 1);

if (protoConstr === null) {
return `${res} <${inspect(firstProto, {
...ctx,
customInspect: false,
depth: -1
})}>`;
}

return `${res} <${protoConstr}>`;
}

function getPrefix(constructor, tag, fallback) {
Expand Down Expand Up @@ -581,7 +594,7 @@ function formatValue(ctx, value, recurseTimes, typedArray) {
function formatRaw(ctx, value, recurseTimes, typedArray) {
let keys;

const constructor = getConstructorName(value, ctx);
const constructor = getConstructorName(value, ctx, recurseTimes);
let tag = value[Symbol.toStringTag];
// Only list the tag in case it's non-enumerable / not an own property.
// Otherwise we'd print this twice.
Expand Down
15 changes: 15 additions & 0 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2114,6 +2114,21 @@ assert.strictEqual(
inspect(obj),
"Array <[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }"
);

StorageObject.prototype = Object.create(null);
Object.setPrototypeOf(StorageObject.prototype, Object.create(null));
Object.setPrototypeOf(
Object.getPrototypeOf(StorageObject.prototype),
Object.create(null)
);
assert.strictEqual(
util.inspect(new StorageObject()),
'StorageObject <Object <Object <[Object: null prototype] {}>>> {}'
);
assert.strictEqual(
util.inspect(new StorageObject(), { depth: 1 }),
'StorageObject <Object <Object <Complex prototype>>> {}'
);
}

// Check that the fallback always works.
Expand Down

0 comments on commit 1fa4037

Please sign in to comment.