console,util: fix missing recursion end while inspecting prototypes

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: https://github.com/nodejs/node/pull/29647
Fixes: https://github.com/nodejs/node/issues/29646
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
This commit is contained in:
Ruben Bridgewater 2019-09-21 21:26:02 +02:00 committed by Rich Trott
parent 0c32ca96c8
commit 1fa403762c
2 changed files with 34 additions and 6 deletions

View File

@ -351,7 +351,7 @@ function getEmptyFormatArray() {
return [];
}
function getConstructorName(obj, ctx) {
function getConstructorName(obj, ctx, recurseTimes) {
let firstProto;
const tmp = obj;
while (obj) {
@ -372,12 +372,25 @@ function getConstructorName(obj, ctx) {
return null;
}
return `${internalGetConstructorName(tmp)} <${inspect(firstProto, {
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
customInspect: false,
depth: -1
})}>`;
}
return `${res} <${protoConstr}>`;
}
function getPrefix(constructor, tag, fallback) {
if (constructor === null) {
if (tag !== '') {
@ -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.

View File

@ -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.