From f19bf16317c25efb1f67e2f81d812dd98dd7076d Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 19 Aug 2016 00:44:38 +0200 Subject: [PATCH] util: allow returning `this` from custom inspect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a custom inspection function returned `this`, use that value for further formatting instead of going into infinite recursion. This is particularly useful when combined with `util.inspect.custom` because returning `this` from such a method makes it easy to have an `inspect()` function that is ignored by `util.inspect` without actually having to provide an alternative for custom inspection. PR-URL: https://github.com/nodejs/node/pull/8174 Reviewed-By: James M Snell Reviewed-By: Michaƫl Zasso PR-URL: https://github.com/nodejs/node/pull/8437 Reviewed-By: James M Snell Reviewed-By: Jeremiah Senkpiel --- lib/util.js | 11 ++++++++--- test/parallel/test-util-inspect.js | 10 ++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/util.js b/lib/util.js index 256fafc65edfa9..b4ff85f9a6edb1 100644 --- a/lib/util.js +++ b/lib/util.js @@ -362,10 +362,15 @@ function formatValue(ctx, value, recurseTimes) { // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { let ret = maybeCustomInspect.call(value, recurseTimes, ctx); - if (typeof ret !== 'string') { - ret = formatValue(ctx, ret, recurseTimes); + + // If the custom inspection method returned `this`, don't go into + // infinite recursion. + if (ret !== value) { + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; } - return ret; } } diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 4f0c3aebf63d12..15a444fdab648e 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -567,6 +567,16 @@ assert.doesNotThrow(function() { ); } +{ + // Returning `this` from a custom inspection function works. + assert.strictEqual(util.inspect({ a: 123, inspect() { return this; } }), + '{ a: 123, inspect: [Function: inspect] }'); + + const subject = { a: 123, [util.inspect.custom]() { return this; } }; + assert.strictEqual(util.inspect(subject), + '{ a: 123 }'); +} + // util.inspect with "colors" option should produce as many lines as without it function test_lines(input) { var count_lines = function(str) {