Skip to content

Commit cdf6471

Browse files
BridgeARtargos
authored andcommitted
util: fix sparse array inspection
For very special sparse arrays it was possible that util.inspect visualized the entries not in the intended way. PR-URL: #22283 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 2ed22df commit cdf6471

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

lib/util.js

+18-22
Original file line numberDiff line numberDiff line change
@@ -843,33 +843,29 @@ function formatNamespaceObject(ctx, value, recurseTimes, keys) {
843843
function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
844844
const output = [];
845845
const keyLen = keys.length;
846-
let visibleLength = 0;
847846
let i = 0;
848-
if (keyLen !== 0 && numberRegExp.test(keys[0])) {
849-
for (const key of keys) {
850-
if (visibleLength === maxLength)
847+
for (const key of keys) {
848+
if (output.length === maxLength)
849+
break;
850+
const index = +key;
851+
// Arrays can only have up to 2^32 - 1 entries
852+
if (index > 2 ** 32 - 2)
853+
break;
854+
if (`${i}` !== key) {
855+
if (!numberRegExp.test(key))
851856
break;
852-
const index = +key;
853-
// Arrays can only have up to 2^32 - 1 entries
854-
if (index > 2 ** 32 - 2)
857+
const emptyItems = index - i;
858+
const ending = emptyItems > 1 ? 's' : '';
859+
const message = `<${emptyItems} empty item${ending}>`;
860+
output.push(ctx.stylize(message, 'undefined'));
861+
i = index;
862+
if (output.length === maxLength)
855863
break;
856-
if (i !== index) {
857-
if (!numberRegExp.test(key))
858-
break;
859-
const emptyItems = index - i;
860-
const ending = emptyItems > 1 ? 's' : '';
861-
const message = `<${emptyItems} empty item${ending}>`;
862-
output.push(ctx.stylize(message, 'undefined'));
863-
i = index;
864-
if (++visibleLength === maxLength)
865-
break;
866-
}
867-
output.push(formatProperty(ctx, value, recurseTimes, key, 1));
868-
visibleLength++;
869-
i++;
870864
}
865+
output.push(formatProperty(ctx, value, recurseTimes, key, 1));
866+
i++;
871867
}
872-
if (i < valLen && visibleLength !== maxLength) {
868+
if (i < valLen && output.length !== maxLength) {
873869
const len = valLen - i;
874870
const ending = len > 1 ? 's' : '';
875871
const message = `<${len} empty item${ending}>`;

test/parallel/test-util-inspect.js

+13
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,19 @@ assert.strictEqual(
345345
"[ <2 empty items>, '00': 1, '01': 2 ]");
346346
assert.strictEqual(util.inspect(arr2, { showHidden: true }),
347347
"[ <2 empty items>, [length]: 2, '00': 1, '01': 2 ]");
348+
delete arr2['00'];
349+
arr2[0] = 0;
350+
assert.strictEqual(util.inspect(arr2),
351+
"[ 0, <1 empty item>, '01': 2 ]");
352+
assert.strictEqual(util.inspect(arr2, { showHidden: true }),
353+
"[ 0, <1 empty item>, [length]: 2, '01': 2 ]");
354+
delete arr2['01'];
355+
arr2[2 ** 32 - 2] = 'max';
356+
arr2[2 ** 32 - 1] = 'too far';
357+
assert.strictEqual(
358+
util.inspect(arr2),
359+
"[ 0, <4294967293 empty items>, 'max', '4294967295': 'too far' ]"
360+
);
348361

349362
const arr3 = [];
350363
arr3[-1] = -1;

0 commit comments

Comments
 (0)