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: https://github.com/nodejs/node/pull/22283 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
1abc613b32
commit
6bba368ccf
40
lib/util.js
40
lib/util.js
@ -971,33 +971,29 @@ function formatNamespaceObject(ctx, value, recurseTimes, keys) {
|
|||||||
function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
|
function formatSpecialArray(ctx, value, recurseTimes, keys, maxLength, valLen) {
|
||||||
const output = [];
|
const output = [];
|
||||||
const keyLen = keys.length;
|
const keyLen = keys.length;
|
||||||
let visibleLength = 0;
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
if (keyLen !== 0 && numberRegExp.test(keys[0])) {
|
for (const key of keys) {
|
||||||
for (const key of keys) {
|
if (output.length === maxLength)
|
||||||
if (visibleLength === maxLength)
|
break;
|
||||||
|
const index = +key;
|
||||||
|
// Arrays can only have up to 2^32 - 1 entries
|
||||||
|
if (index > 2 ** 32 - 2)
|
||||||
|
break;
|
||||||
|
if (`${i}` !== key) {
|
||||||
|
if (!numberRegExp.test(key))
|
||||||
break;
|
break;
|
||||||
const index = +key;
|
const emptyItems = index - i;
|
||||||
// Arrays can only have up to 2^32 - 1 entries
|
const ending = emptyItems > 1 ? 's' : '';
|
||||||
if (index > 2 ** 32 - 2)
|
const message = `<${emptyItems} empty item${ending}>`;
|
||||||
|
output.push(ctx.stylize(message, 'undefined'));
|
||||||
|
i = index;
|
||||||
|
if (output.length === maxLength)
|
||||||
break;
|
break;
|
||||||
if (i !== index) {
|
|
||||||
if (!numberRegExp.test(key))
|
|
||||||
break;
|
|
||||||
const emptyItems = index - i;
|
|
||||||
const ending = emptyItems > 1 ? 's' : '';
|
|
||||||
const message = `<${emptyItems} empty item${ending}>`;
|
|
||||||
output.push(ctx.stylize(message, 'undefined'));
|
|
||||||
i = index;
|
|
||||||
if (++visibleLength === maxLength)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
output.push(formatProperty(ctx, value, recurseTimes, key, 1));
|
|
||||||
visibleLength++;
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
output.push(formatProperty(ctx, value, recurseTimes, key, 1));
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
if (i < valLen && visibleLength !== maxLength) {
|
if (i < valLen && output.length !== maxLength) {
|
||||||
const len = valLen - i;
|
const len = valLen - i;
|
||||||
const ending = len > 1 ? 's' : '';
|
const ending = len > 1 ? 's' : '';
|
||||||
const message = `<${len} empty item${ending}>`;
|
const message = `<${len} empty item${ending}>`;
|
||||||
|
@ -344,6 +344,19 @@ assert.strictEqual(
|
|||||||
"[ <2 empty items>, '00': 1, '01': 2 ]");
|
"[ <2 empty items>, '00': 1, '01': 2 ]");
|
||||||
assert.strictEqual(util.inspect(arr2, { showHidden: true }),
|
assert.strictEqual(util.inspect(arr2, { showHidden: true }),
|
||||||
"[ <2 empty items>, [length]: 2, '00': 1, '01': 2 ]");
|
"[ <2 empty items>, [length]: 2, '00': 1, '01': 2 ]");
|
||||||
|
delete arr2['00'];
|
||||||
|
arr2[0] = 0;
|
||||||
|
assert.strictEqual(util.inspect(arr2),
|
||||||
|
"[ 0, <1 empty item>, '01': 2 ]");
|
||||||
|
assert.strictEqual(util.inspect(arr2, { showHidden: true }),
|
||||||
|
"[ 0, <1 empty item>, [length]: 2, '01': 2 ]");
|
||||||
|
delete arr2['01'];
|
||||||
|
arr2[2 ** 32 - 2] = 'max';
|
||||||
|
arr2[2 ** 32 - 1] = 'too far';
|
||||||
|
assert.strictEqual(
|
||||||
|
util.inspect(arr2),
|
||||||
|
"[ 0, <4294967293 empty items>, 'max', '4294967295': 'too far' ]"
|
||||||
|
);
|
||||||
|
|
||||||
const arr3 = [];
|
const arr3 = [];
|
||||||
arr3[-1] = -1;
|
arr3[-1] = -1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user