From 2b8724114a3ae9e40ecdbb355df0fb65c1cc8ad1 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 21 Apr 2016 10:29:24 -0700 Subject: [PATCH] util: truncate inspect array and typed array As an alternative to https://github.com/nodejs/node/pull/5070, set the max length of Arrays/TypedArrays in util.inspect() to `100` and provide a `maxArrayLength` option to override. --- doc/api/util.md | 4 +++ lib/util.js | 19 +++++++++-- test/parallel/test-util-inspect.js | 55 ++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/doc/api/util.md b/doc/api/util.md index 8ef4b0dfcc564d..178e0cdb082404 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -183,6 +183,10 @@ formatted string: will be introspected to show their `target` and `hander` objects. Defaults to `false`. + - `maxArrayLength` - specifies the maximum number of Array and TypedArray + elements to include when formatting. Defaults to `100`. Set to `null` to + show all array elements. Set to `0` or negative to show no array elements. + Example of inspecting all properties of the `util` object: ```js diff --git a/lib/util.js b/lib/util.js index 69df2501997309..d430bfd23df02e 100644 --- a/lib/util.js +++ b/lib/util.js @@ -6,6 +6,7 @@ const internalUtil = require('internal/util'); const binding = process.binding('util'); const isError = internalUtil.isError; +const kDefaultMaxLength = 100; var Debug; @@ -141,6 +142,8 @@ function inspect(obj, opts) { if (ctx.customInspect === undefined) ctx.customInspect = true; if (ctx.showProxy === undefined) ctx.showProxy = false; if (ctx.colors) ctx.stylize = stylizeWithColor; + if (ctx.maxArrayLength === undefined) ctx.maxArrayLength = kDefaultMaxLength; + if (ctx.maxArrayLength === null) ctx.maxArrayLength = Infinity; return formatValue(ctx, obj, ctx.depth); } exports.inspect = inspect; @@ -579,7 +582,9 @@ function formatObject(ctx, value, recurseTimes, visibleKeys, keys) { function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; - for (var i = 0, l = value.length; i < l; ++i) { + const maxLength = Math.min(Math.max(0, ctx.maxArrayLength), value.length); + const remaining = value.length - maxLength; + for (var i = 0; i < maxLength; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); @@ -587,6 +592,9 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { output.push(''); } } + if (remaining > 0) { + output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); + } keys.forEach(function(key) { if (typeof key === 'symbol' || !key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, @@ -598,9 +606,14 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { function formatTypedArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = new Array(value.length); - for (var i = 0, l = value.length; i < l; ++i) + const maxLength = Math.min(Math.max(0, ctx.maxArrayLength), value.length); + const remaining = value.length - maxLength; + var output = new Array(maxLength); + for (var i = 0; i < maxLength; ++i) output[i] = formatNumber(ctx, value[i]); + if (remaining > 0) { + output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); + } for (const key of keys) { if (typeof key === 'symbol' || !key.match(/^\d+$/)) { output.push( diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 9e713cf16c542b..d2af5014b241f5 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -648,3 +648,58 @@ checkAlignment(new Map(big_array.map(function(y) { return [y, null]; }))); const x = Object.create(null); assert.equal(util.inspect(x), '{}'); } + +// The following maxArrayLength tests were introduced after v6.0.0 was released. +// Do not backport to v5/v4 unless all of +// https://github.com/nodejs/node/pull/6334 is backported. +{ + const x = Array(101); + assert(/1 more item/.test(util.inspect(x))); +} + +{ + const x = Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: 101}))); +} + +{ + const x = Array(101); + assert(/^\[ ... 101 more items \]$/.test( + util.inspect(x, {maxArrayLength: 0}))); +} + +{ + const x = new Uint8Array(101); + assert(/1 more item/.test(util.inspect(x))); +} + +{ + const x = new Uint8Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: 101}))); +} + +{ + const x = new Uint8Array(101); + assert(/\[ ... 101 more items \]$/.test( + util.inspect(x, {maxArrayLength: 0}))); +} + +{ + const x = Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: null}))); +} + +{ + const x = Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: Infinity}))); +} + +{ + const x = new Uint8Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: null}))); +} + +{ + const x = new Uint8Array(101); + assert(!/1 more item/.test(util.inspect(x, {maxArrayLength: Infinity}))); +}