Skip to content

Commit 5b47f84

Browse files
BridgeARjasnell
authored andcommitted
util: fix out of bounds indices in util.inspect
This fixes a issue brought up in #15288. PR-URL: #14881 Refs: #15288 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent 9e8b1b3 commit 5b47f84

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

lib/util.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,9 @@ function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
652652
if (visibleLength === maxLength)
653653
break;
654654
const index = +key;
655+
// Arrays can only have up to 2^32 - 1 entries
656+
if (index > 2 ** 32 - 2)
657+
break;
655658
if (i !== index) {
656659
if (!numberRegExp.test(key))
657660
break;
@@ -674,6 +677,8 @@ function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
674677
const message = `<${len} empty item${ending}>`;
675678
output.push(ctx.stylize(message, 'undefined'));
676679
i = valLen;
680+
if (keyLen === 0)
681+
return output;
677682
}
678683
const remaining = valLen - i;
679684
if (remaining > 0) {
@@ -687,13 +692,18 @@ function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
687692
// The array is not sparse
688693
for (i = valLen; i < keyLen; i++)
689694
output.push(formatProperty(ctx, value, recurseTimes, keys[i], 2));
690-
} else if (keyLen !== 0 && keys[keyLen - 1] !== `${valLen - 1}`) {
691-
for (const key of keys) {
692-
// Skip regular indices
693-
if (!numberRegExp.test(key)) {
694-
output.push(formatProperty(ctx, value, recurseTimes, key, 2));
695-
}
695+
} else if (keys[keyLen - 1] !== `${valLen - 1}`) {
696+
const extra = [];
697+
// Only handle special keys
698+
var key;
699+
for (i = keys.length - 1; i >= 0; i--) {
700+
key = keys[i];
701+
if (numberRegExp.test(key) && +key < 2 ** 32 - 1)
702+
break;
703+
extra.push(formatProperty(ctx, value, recurseTimes, key, 2));
696704
}
705+
for (i = extra.length - 1; i >= 0; i--)
706+
output.push(extra[i]);
697707
}
698708
return output;
699709
}

test/parallel/test-util-inspect.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,29 @@ assert.strictEqual(
361361
assert.strictEqual(util.inspect(arr3), "[ '-1': -1 ]");
362362
}
363363

364+
// Indices out of bounds
365+
{
366+
const arr = [];
367+
arr[2 ** 32] = true; // not a valid array index
368+
assert.strictEqual(util.inspect(arr), "[ '4294967296': true ]");
369+
arr[0] = true;
370+
arr[10] = true;
371+
assert.strictEqual(util.inspect(arr),
372+
"[ true, <9 empty items>, true, '4294967296': true ]");
373+
arr[2 ** 32 - 2] = true;
374+
arr[2 ** 32 - 1] = true;
375+
arr[2 ** 32 + 1] = true;
376+
delete arr[0];
377+
delete arr[10];
378+
assert.strictEqual(util.inspect(arr),
379+
['[ <4294967294 empty items>,',
380+
'true,',
381+
"'4294967296': true,",
382+
"'4294967295': true,",
383+
"'4294967297': true ]"
384+
].join('\n '));
385+
}
386+
364387
// Function with properties
365388
{
366389
const value = () => {};

0 commit comments

Comments
 (0)