Skip to content

Commit 697908e

Browse files
committed
util: improve prototype inspection using inspect() and showHidden
The fast path for the prototype inspection had a bug that caused some prototype properties to be skipped that should in fact be inspected. PR-URL: #31113 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 9b7cf09 commit 697908e

File tree

2 files changed

+28
-13
lines changed

2 files changed

+28
-13
lines changed

lib/internal/util/inspect.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -465,10 +465,10 @@ function getConstructorName(obj, ctx, recurseTimes, protoProps) {
465465
typeof descriptor.value === 'function' &&
466466
descriptor.value.name !== '') {
467467
if (protoProps !== undefined &&
468-
!builtInObjects.has(descriptor.value.name)) {
469-
const isProto = firstProto !== undefined;
468+
(firstProto !== obj ||
469+
!builtInObjects.has(descriptor.value.name))) {
470470
addPrototypeProperties(
471-
ctx, tmp, obj, recurseTimes, isProto, protoProps);
471+
ctx, tmp, firstProto || tmp, recurseTimes, protoProps);
472472
}
473473
return descriptor.value.name;
474474
}
@@ -506,12 +506,12 @@ function getConstructorName(obj, ctx, recurseTimes, protoProps) {
506506
// This function has the side effect of adding prototype properties to the
507507
// `output` argument (which is an array). This is intended to highlight user
508508
// defined prototype properties.
509-
function addPrototypeProperties(ctx, main, obj, recurseTimes, isProto, output) {
509+
function addPrototypeProperties(ctx, main, obj, recurseTimes, output) {
510510
let depth = 0;
511511
let keys;
512512
let keySet;
513513
do {
514-
if (!isProto) {
514+
if (depth !== 0 || main === obj) {
515515
obj = ObjectGetPrototypeOf(obj);
516516
// Stop as soon as a null prototype is encountered.
517517
if (obj === null) {
@@ -524,8 +524,6 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, isProto, output) {
524524
builtInObjects.has(descriptor.value.name)) {
525525
return;
526526
}
527-
} else {
528-
isProto = false;
529527
}
530528

531529
if (depth === 0) {

test/parallel/test-util-inspect.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,7 +1695,8 @@ util.inspect(process);
16951695
' 1,',
16961696
' 2,',
16971697
' [length]: 2',
1698-
' ]',
1698+
' ],',
1699+
" [Symbol(Symbol.toStringTag)]: 'Set Iterator'",
16991700
' } => <ref *1> [Map Iterator] {',
17001701
' Uint8Array(0) [',
17011702
' [BYTES_PER_ELEMENT]: 1,',
@@ -1707,7 +1708,8 @@ util.inspect(process);
17071708
' foo: true',
17081709
' }',
17091710
' ],',
1710-
' [Circular *1]',
1711+
' [Circular *1],',
1712+
" [Symbol(Symbol.toStringTag)]: 'Map Iterator'",
17111713
' }',
17121714
'}'
17131715
].join('\n');
@@ -1734,15 +1736,19 @@ util.inspect(process);
17341736
' [byteOffset]: 0,',
17351737
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
17361738
' ],',
1737-
' [Set Iterator] { [ 1, 2, [length]: 2 ] } => <ref *1> [Map Iterator] {',
1739+
' [Set Iterator] {',
1740+
' [ 1, 2, [length]: 2 ],',
1741+
" [Symbol(Symbol.toStringTag)]: 'Set Iterator'",
1742+
' } => <ref *1> [Map Iterator] {',
17381743
' Uint8Array(0) [',
17391744
' [BYTES_PER_ELEMENT]: 1,',
17401745
' [length]: 0,',
17411746
' [byteLength]: 0,',
17421747
' [byteOffset]: 0,',
17431748
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
17441749
' ],',
1745-
' [Circular *1]',
1750+
' [Circular *1],',
1751+
" [Symbol(Symbol.toStringTag)]: 'Map Iterator'",
17461752
' }',
17471753
'}'
17481754
].join('\n');
@@ -1772,7 +1778,9 @@ util.inspect(process);
17721778
' [Set Iterator] {',
17731779
' [ 1,',
17741780
' 2,',
1775-
' [length]: 2 ] } => <ref *1> [Map Iterator] {',
1781+
' [length]: 2 ],',
1782+
' [Symbol(Symbol.toStringTag)]:',
1783+
" 'Set Iterator' } => <ref *1> [Map Iterator] {",
17761784
' Uint8Array(0) [',
17771785
' [BYTES_PER_ELEMENT]: 1,',
17781786
' [length]: 0,',
@@ -1781,7 +1789,9 @@ util.inspect(process);
17811789
' [buffer]: ArrayBuffer {',
17821790
' byteLength: 0,',
17831791
' foo: true } ],',
1784-
' [Circular *1] } }'
1792+
' [Circular *1],',
1793+
' [Symbol(Symbol.toStringTag)]:',
1794+
" 'Map Iterator' } }"
17851795
].join('\n');
17861796

17871797
assert.strict.equal(out, expected);
@@ -2680,4 +2690,11 @@ assert.strictEqual(
26802690
' \x1B[2m[def]: \x1B[36m[Getter/Setter]\x1B[39m\x1B[22m\n' +
26812691
'}'
26822692
);
2693+
2694+
const obj = Object.create({ abc: true, def: 5, toString() {} });
2695+
assert.strictEqual(
2696+
inspect(obj, { showHidden: true, colors: true }),
2697+
'{ \x1B[2mabc: \x1B[33mtrue\x1B[39m\x1B[22m, ' +
2698+
'\x1B[2mdef: \x1B[33m5\x1B[39m\x1B[22m }'
2699+
);
26832700
}

0 commit comments

Comments
 (0)