Description
While experimenting with prototypes, I found that node's console inspector seems to crash when given an Array object with a custom prototype that's missing an iterator definition.
-
Version:
v11.6.0 -
Platform:
Darwin Lazarus.local 17.7.0 Darwin Kernel Version 17.7.0: Fri Nov 2 20:43:16 PDT 2018; root:xnu-4570.71.17~1/RELEASE_X86_64 x86_64 -
Subsystem:
internal/util/inspect.js -
Test case
function ArrayX() {
let arr = new Array(...arguments);
Object.setPrototypeOf(arr, ArrayX.prototype);
return arr;
};
ArrayX.prototype = Object.create(null);
ArrayX.prototype.constructor = ArrayX;
// uncomment to work around the crash
//ArrayX.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
let arr = new ArrayX(1, 2, 3);
console.log('proto is', Object.getPrototypeOf(arr));
// inspector crashes below:
console.log('obj is', arr);
Output:
$ node inspect-fail.js
proto is ArrayX { constructor: [Function: ArrayX] }
internal/util/inspect.js:479
newVal = new clazz(value.length);
^
TypeError: clazz is not a constructor
at noPrototypeIterator (internal/util/inspect.js:479:14)
at formatRaw (internal/util/inspect.js:725:31)
at formatValue (internal/util/inspect.js:545:10)
at inspect (internal/util/inspect.js:194:10)
at Object.formatWithOptions (util.js:180:18)
at Console.(anonymous function) (console.js:199:15)
at Console.log (console.js:210:31)
at Object.<anonymous> (/Users/brion/src/turtle-world/inspect-fail.js:18:9)
at Module._compile (internal/modules/cjs/loader.js:721:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
In this case, the checks for regular arrays fail because the class has no Symbol.iterator
method, so the inspector ends up in the case for noPrototypeIterator
. This code has several branch points that attempt to use prototypes as constructors for Map, Set, and Array-based objects, all of which look like they will fail if reached. (There is a fallback for null prototypes added recently, which does not help as there is a prototype here. The prototype itself has a null prototype, but that's not found or followed.)
Workaround: complete the custom Array prototype and include an iterator definition.