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: https://github.com/nodejs/node/pull/25457 Fixes: https://github.com/nodejs/node/issues/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>
This commit is contained in:
parent
27f9a55cf6
commit
2c0a75118c
@ -463,28 +463,22 @@ function clazzWithNullPrototype(clazz, name) {
|
|||||||
function noPrototypeIterator(ctx, value, recurseTimes) {
|
function noPrototypeIterator(ctx, value, recurseTimes) {
|
||||||
let newVal;
|
let newVal;
|
||||||
if (isSet(value)) {
|
if (isSet(value)) {
|
||||||
const clazz = Object.getPrototypeOf(value) ||
|
const clazz = clazzWithNullPrototype(Set, 'Set');
|
||||||
clazzWithNullPrototype(Set, 'Set');
|
|
||||||
newVal = new clazz(setValues(value));
|
newVal = new clazz(setValues(value));
|
||||||
} else if (isMap(value)) {
|
} else if (isMap(value)) {
|
||||||
const clazz = Object.getPrototypeOf(value) ||
|
const clazz = clazzWithNullPrototype(Map, 'Map');
|
||||||
clazzWithNullPrototype(Map, 'Map');
|
|
||||||
newVal = new clazz(mapEntries(value));
|
newVal = new clazz(mapEntries(value));
|
||||||
} else if (Array.isArray(value)) {
|
} else if (Array.isArray(value)) {
|
||||||
const clazz = Object.getPrototypeOf(value) ||
|
const clazz = clazzWithNullPrototype(Array, 'Array');
|
||||||
clazzWithNullPrototype(Array, 'Array');
|
|
||||||
newVal = new clazz(value.length);
|
newVal = new clazz(value.length);
|
||||||
} else if (isTypedArray(value)) {
|
} else if (isTypedArray(value)) {
|
||||||
let clazz = Object.getPrototypeOf(value);
|
|
||||||
if (!clazz) {
|
|
||||||
const constructor = findTypedConstructor(value);
|
const constructor = findTypedConstructor(value);
|
||||||
clazz = clazzWithNullPrototype(constructor, constructor.name);
|
const clazz = clazzWithNullPrototype(constructor, constructor.name);
|
||||||
}
|
|
||||||
newVal = new clazz(value);
|
newVal = new clazz(value);
|
||||||
}
|
}
|
||||||
if (newVal) {
|
if (newVal !== undefined) {
|
||||||
Object.defineProperties(newVal, Object.getOwnPropertyDescriptors(value));
|
Object.defineProperties(newVal, Object.getOwnPropertyDescriptors(value));
|
||||||
return formatValue(ctx, newVal, recurseTimes);
|
return formatRaw(ctx, newVal, recurseTimes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -728,10 +722,12 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
|
|||||||
} else {
|
} else {
|
||||||
// The input prototype got manipulated. Special handle these. We have to
|
// The input prototype got manipulated. Special handle these. We have to
|
||||||
// rebuild the information so we are able to display everything.
|
// rebuild the information so we are able to display everything.
|
||||||
|
if (constructor === null) {
|
||||||
const specialIterator = noPrototypeIterator(ctx, value, recurseTimes);
|
const specialIterator = noPrototypeIterator(ctx, value, recurseTimes);
|
||||||
if (specialIterator) {
|
if (specialIterator) {
|
||||||
return specialIterator;
|
return specialIterator;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (isMapIterator(value)) {
|
if (isMapIterator(value)) {
|
||||||
braces = [`[${tag || 'Map Iterator'}] {`, '}'];
|
braces = [`[${tag || 'Map Iterator'}] {`, '}'];
|
||||||
formatter = formatMapIterator;
|
formatter = formatMapIterator;
|
||||||
|
@ -1853,6 +1853,16 @@ assert.strictEqual(
|
|||||||
util.inspect(new StorageObject()),
|
util.inspect(new StorageObject()),
|
||||||
'<[Object: null prototype] {}> {}'
|
'<[Object: null prototype] {}> {}'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
obj = [1, 2, 3];
|
||||||
|
Object.setPrototypeOf(obj, Number.prototype);
|
||||||
|
assert.strictEqual(inspect(obj), "Number { '0': 1, '1': 2, '2': 3 }");
|
||||||
|
|
||||||
|
Object.setPrototypeOf(obj, Object.create(null));
|
||||||
|
assert.strictEqual(
|
||||||
|
inspect(obj),
|
||||||
|
"<[Object: null prototype] {}> { '0': 1, '1': 2, '2': 3 }"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the fallback always works.
|
// Check that the fallback always works.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user