diff options
-rw-r--r-- | doc/api/util.md | 4 | ||||
-rw-r--r-- | lib/internal/util/inspect.js | 8 | ||||
-rw-r--r-- | test/parallel/test-util-inspect.js | 20 |
3 files changed, 26 insertions, 6 deletions
diff --git a/doc/api/util.md b/doc/api/util.md index 9db263632e..b1d4854997 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -388,6 +388,10 @@ stream.write('With ES6'); <!-- YAML added: v0.3.0 changes: + - version: REPLACEME + pr-url: https://github.com/nodejs/node/pull/24971 + description: Internal properties no longer appear in the context argument + of a custom inspection function. - version: v11.7.0 pr-url: https://github.com/nodejs/node/pull/25006 description: ArrayBuffers now also show their binary contents. diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index 9099c33e9e..9a1a0f9f03 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -516,10 +516,14 @@ function formatValue(ctx, value, recurseTimes, typedArray) { maybeCustom !== inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { + // Remove some internal properties from the options before passing it + // through to the user function. This also prevents option manipulation. + // eslint-disable-next-line no-unused-vars + const { budget, seen, indentationLvl, ...plainCtx } = ctx; // This makes sure the recurseTimes are reported as before while using // a counter internally. const depth = ctx.depth === null ? null : ctx.depth - recurseTimes; - const ret = maybeCustom.call(value, depth, ctx); + const ret = maybeCustom.call(value, depth, plainCtx); // If the custom inspection method returned `this`, don't go into // infinite recursion. @@ -527,7 +531,7 @@ function formatValue(ctx, value, recurseTimes, typedArray) { if (typeof ret !== 'string') { return formatValue(ctx, ret, recurseTimes); } - return ret; + return ret.replace(/\n/g, `\n${' '.repeat(ctx.indentationLvl)}`); } } } diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 21a0634323..4e9f5ac004 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -775,9 +775,21 @@ util.inspect({ hasOwnProperty: null }); assert.strictEqual(util.inspect(subject), "{ foo: 'bar' }"); - subject[util.inspect.custom] = (depth, opts) => { - assert.strictEqual(opts.customInspectOptions, true); - }; + subject[util.inspect.custom] = common.mustCall((depth, opts) => { + const clone = { ...opts }; + // This might change at some point but for now we keep the stylize function. + // The function should either be documented or an alternative should be + // implemented. + assert.strictEqual(typeof opts.stylize, 'function'); + assert.strictEqual(opts.seen, undefined); + assert.strictEqual(opts.budget, undefined); + assert.strictEqual(opts.indentationLvl, undefined); + assert.strictEqual(opts.showHidden, false); + opts.showHidden = true; + return { [util.inspect.custom]: common.mustCall((depth, opts2) => { + assert.deepStrictEqual(clone, opts2); + }) }; + }); util.inspect(subject, { customInspectOptions: true }); @@ -1593,7 +1605,7 @@ util.inspect(process); ); const longList = util.inspect(list, { depth: Infinity }); const match = longList.match(/next/g); - assert(match.length > 1000 && match.length < 10000); + assert(match.length > 500 && match.length < 10000); assert(longList.includes('[Object: Inspection interrupted ' + 'prematurely. Maximum call stack size exceeded.]')); } |