Skip to content

Commit

Permalink
util: improve prototype inspection using inspect() and showHidden
Browse files Browse the repository at this point in the history
The fast path for the prototype inspection had a bug that caused some
prototype properties to be skipped that should in fact be inspected.

Backport-PR-URL: #31431
PR-URL: #31113
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
BridgeAR authored and BethGriggs committed Feb 6, 2020
1 parent 7a855f5 commit a1d36db
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
12 changes: 5 additions & 7 deletions lib/internal/util/inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,10 +467,10 @@ function getConstructorName(obj, ctx, recurseTimes, protoProps) {
typeof descriptor.value === 'function' &&
descriptor.value.name !== '') {
if (protoProps !== undefined &&
!builtInObjects.has(descriptor.value.name)) {
const isProto = firstProto !== undefined;
(firstProto !== obj ||
!builtInObjects.has(descriptor.value.name))) {
addPrototypeProperties(
ctx, tmp, obj, recurseTimes, isProto, protoProps);
ctx, tmp, firstProto || tmp, recurseTimes, protoProps);
}
return descriptor.value.name;
}
Expand Down Expand Up @@ -508,12 +508,12 @@ function getConstructorName(obj, ctx, recurseTimes, protoProps) {
// This function has the side effect of adding prototype properties to the
// `output` argument (which is an array). This is intended to highlight user
// defined prototype properties.
function addPrototypeProperties(ctx, main, obj, recurseTimes, isProto, output) {
function addPrototypeProperties(ctx, main, obj, recurseTimes, output) {
let depth = 0;
let keys;
let keySet;
do {
if (!isProto) {
if (depth !== 0 || main === obj) {
obj = ObjectGetPrototypeOf(obj);
// Stop as soon as a null prototype is encountered.
if (obj === null) {
Expand All @@ -526,8 +526,6 @@ function addPrototypeProperties(ctx, main, obj, recurseTimes, isProto, output) {
builtInObjects.has(descriptor.value.name)) {
return;
}
} else {
isProto = false;
}

if (depth === 0) {
Expand Down
29 changes: 23 additions & 6 deletions test/parallel/test-util-inspect.js
Original file line number Diff line number Diff line change
Expand Up @@ -1687,7 +1687,8 @@ util.inspect(process);
' 1,',
' 2,',
' [length]: 2',
' ]',
' ],',
" [Symbol(Symbol.toStringTag)]: 'Set Iterator'",
' } => [Map Iterator] {',
' Uint8Array(0) [',
' [BYTES_PER_ELEMENT]: 1,',
Expand All @@ -1699,7 +1700,8 @@ util.inspect(process);
' foo: true',
' }',
' ],',
' [Circular]',
' [Circular],',
" [Symbol(Symbol.toStringTag)]: 'Map Iterator'",
' },',
' [size]: 2',
'}'
Expand Down Expand Up @@ -1727,15 +1729,19 @@ util.inspect(process);
' [byteOffset]: 0,',
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
' ],',
' [Set Iterator] { [ 1, 2, [length]: 2 ] } => [Map Iterator] {',
' [Set Iterator] {',
' [ 1, 2, [length]: 2 ],',
" [Symbol(Symbol.toStringTag)]: 'Set Iterator'",
' } => [Map Iterator] {',
' Uint8Array(0) [',
' [BYTES_PER_ELEMENT]: 1,',
' [length]: 0,',
' [byteLength]: 0,',
' [byteOffset]: 0,',
' [buffer]: ArrayBuffer { byteLength: 0, foo: true }',
' ],',
' [Circular]',
' [Circular],',
" [Symbol(Symbol.toStringTag)]: 'Map Iterator'",
' },',
' [size]: 2',
'}'
Expand Down Expand Up @@ -1767,7 +1773,9 @@ util.inspect(process);
' [Set Iterator] {',
' [ 1,',
' 2,',
' [length]: 2 ] } => [Map Iterator] {',
' [length]: 2 ],',
' [Symbol(Symbol.toStringTag)]:',
" 'Set Iterator' } => [Map Iterator] {",
' Uint8Array(0) [',
' [BYTES_PER_ELEMENT]: 1,',
' [length]: 0,',
Expand All @@ -1776,7 +1784,9 @@ util.inspect(process);
' [buffer]: ArrayBuffer {',
' byteLength: 0,',
' foo: true } ],',
' [Circular] },',
' [Circular],',
' [Symbol(Symbol.toStringTag)]:',
" 'Map Iterator' },",
' [size]: 2 }'
].join('\n');

Expand Down Expand Up @@ -2678,4 +2688,11 @@ assert.strictEqual(
' \x1B[2m[def]: \x1B[36m[Getter/Setter]\x1B[39m\x1B[22m\n' +
'}'
);

const obj = Object.create({ abc: true, def: 5, toString() {} });
assert.strictEqual(
inspect(obj, { showHidden: true, colors: true }),
'{ \x1B[2mabc: \x1B[33mtrue\x1B[39m\x1B[22m, ' +
'\x1B[2mdef: \x1B[33m5\x1B[39m\x1B[22m }'
);
}

0 comments on commit a1d36db

Please sign in to comment.