Skip to content

Commit 338f456

Browse files
BridgeARaddaleax
authored andcommitted
util: fix iterable types with special prototype
The fallback should only be taken for a null prototype. If an iterable data type (e.g., Array) has a prototype without `Symbol.iterator`, just try the best to visualize it as object. PR-URL: #25457Fixes: #25451 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 4c207d9 commit 338f456

2 files changed

Lines changed: 22 additions & 16 deletions

File tree

‎lib/internal/util/inspect.js‎

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -463,28 +463,22 @@ function clazzWithNullPrototype(clazz, name) {
463463
functionnoPrototypeIterator(ctx,value,recurseTimes){
464464
letnewVal;
465465
if(isSet(value)){
466-
constclazz=Object.getPrototypeOf(value)||
467-
clazzWithNullPrototype(Set,'Set');
466+
constclazz=clazzWithNullPrototype(Set,'Set');
468467
newVal=newclazz(setValues(value));
469468
}elseif(isMap(value)){
470-
constclazz=Object.getPrototypeOf(value)||
471-
clazzWithNullPrototype(Map,'Map');
469+
constclazz=clazzWithNullPrototype(Map,'Map');
472470
newVal=newclazz(mapEntries(value));
473471
}elseif(Array.isArray(value)){
474-
constclazz=Object.getPrototypeOf(value)||
475-
clazzWithNullPrototype(Array,'Array');
472+
constclazz=clazzWithNullPrototype(Array,'Array');
476473
newVal=newclazz(value.length);
477474
}elseif(isTypedArray(value)){
478-
letclazz=Object.getPrototypeOf(value);
479-
if(!clazz){
480-
constconstructor=findTypedConstructor(value);
481-
clazz=clazzWithNullPrototype(constructor,constructor.name);
482-
}
475+
constconstructor=findTypedConstructor(value);
476+
constclazz=clazzWithNullPrototype(constructor,constructor.name);
483477
newVal=newclazz(value);
484478
}
485-
if(newVal){
479+
if(newVal!==undefined){
486480
Object.defineProperties(newVal,Object.getOwnPropertyDescriptors(value));
487-
returnformatValue(ctx,newVal,recurseTimes);
481+
returnformatRaw(ctx,newVal,recurseTimes);
488482
}
489483
}
490484

@@ -728,9 +722,11 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
728722
}else{
729723
// The input prototype got manipulated. Special handle these. We have to
730724
// rebuild the information so we are able to display everything.
731-
constspecialIterator=noPrototypeIterator(ctx,value,recurseTimes);
732-
if(specialIterator){
733-
returnspecialIterator;
725+
if(constructor===null){
726+
constspecialIterator=noPrototypeIterator(ctx,value,recurseTimes);
727+
if(specialIterator){
728+
returnspecialIterator;
729+
}
734730
}
735731
if(isMapIterator(value)){
736732
braces=[`[${tag||'Map Iterator'}] {`,'}'];

‎test/parallel/test-util-inspect.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,16 @@ assert.strictEqual(
18531853
util.inspect(newStorageObject()),
18541854
'<[Object: null prototype] {}> {}'
18551855
);
1856+
1857+
obj=[1,2,3];
1858+
Object.setPrototypeOf(obj,Number.prototype);
1859+
assert.strictEqual(inspect(obj),"Number { '0': 1, '1': 2, '2': 3 }");
1860+
1861+
Object.setPrototypeOf(obj,Object.create(null));
1862+
assert.strictEqual(
1863+
inspect(obj),
1864+
"<[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }"
1865+
);
18561866
}
18571867

18581868
// Check that the fallback always works.

0 commit comments

Comments
 (0)