summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2019-09-21 21:26:02 +0200
committerRich Trott <rtrott@gmail.com>2019-09-23 23:42:10 -0700
commit1fa403762c035dca35bae9a18a4e4c3edf9d55f3 (patch)
tree413ff024a2271a0edf09414fb990df8ee85c3b8d
parent0c32ca96c878488c923022a8828bef541e0df9ae (diff)
downloadandroid-node-v8-1fa403762c035dca35bae9a18a4e4c3edf9d55f3.tar.gz
android-node-v8-1fa403762c035dca35bae9a18a4e4c3edf9d55f3.tar.bz2
android-node-v8-1fa403762c035dca35bae9a18a4e4c3edf9d55f3.zip
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>
-rw-r--r--lib/internal/util/inspect.js25
-rw-r--r--test/parallel/test-util-inspect.js15
2 files changed, 34 insertions, 6 deletions
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index de044447b3..6401e30e92 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} <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) {
@@ -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 64682d9c17..fc0bb345da 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 <Object <Object <[Object: null prototype] {}>>> {}'
+ );
+ assert.strictEqual(
+ util.inspect(new StorageObject(), { depth: 1 }),
+ 'StorageObject <Object <Object <Complex prototype>>> {}'
+ );
}
// Check that the fallback always works.