From d390b6b283ddf6259e0ff8c98d4b36fafe1ca106 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sat, 21 Sep 2019 21:26:02 +0200 Subject: [PATCH] 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. --- lib/internal/util/inspect.js | 25 +++++++++++++++++++------ test/parallel/test-util-inspect.js | 15 +++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 8ab3df8b631b7a..a3664c563ea865 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -351,7 +351,7 @@ function getEmptyFormatArray() { return []; } -function getConstructorName(obj, ctx) { +function getConstructorName(obj, ctx, recurseTimes) { let firstProto; const tmp = obj; while (obj) { @@ -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} `; + } + + 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) { @@ -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. diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 64682d9c17d6d7..fc0bb345da95ce 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -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 >> {}' + ); + assert.strictEqual( + util.inspect(new StorageObject(), { depth: 1 }), + 'StorageObject >> {}' + ); } // Check that the fallback always works.