Description
- Version: Tested on all from 5.11.1 to 7.6.0.
- Platform:
Darwin 15.6.0 Darwin Kernel Version 15.6.0: Thu Sep 1 15:01:16 PDT 2016; root:xnu-3248.60.11~2/RELEASE_X86_64 x86_64
- Subsystem: Util
Problematic code:
Object.prototype.name = "bug"
Object.prototype
Sample run:
Code breaks in stylizeWithColor the following line.
Why?
Because we are printing a property, the call to stylizeWithColor
passes 'name'
as the styleType
where 'name'
style type is actually ignored.
These style types are stored in the plain object inspect.styles
so the execution expects inspect.styles['name']
on the first line of stylizeWithColor
to return undefined
(since it is ignored) and not enter the if
statement.
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType]; // <-- this should return `undefined`
if (style) { // <-- this shouldn't happen
return `\u001b[${inspect.colors[style][0]}m${str}` +
`\u001b[${inspect.colors[style][1]}m`;
} else {
return str;
}
}
However, since we added a "name"
property on Object.prototype
, inspect.styles['name']
doesn't find 'name'
directly but does find it up the [[Prototype]] chain and actually returns the string"bug"
.
function stylizeWithColor(str, styleType) {
var style = inspect.styles[styleType]; // <-- this returns "bug"` because it found it up the [[Prototype]] chain
if (style) { // <-- // <-- this happens because "bug" is truthy
return `\u001b[${inspect.colors[style][0]}m${str}` +
`\u001b[${inspect.colors[style][1]}m`;
} else {
return str;
}
}
This means that the code tries to execute inspect.colors["bug"][0]
, which gives undefined[0]
, and throws the error in the issue.
A funny consequence is that, if we make name
equal to a color value used in inspect.colors
, then the error wouldn't happen and the property name
will be printed in that color.
Proposed solution
Use an object not linked to Object.prototype
for inspect.style
.
const styles = {
'special': 'cyan',
'number': 'yellow',
'boolean': 'yellow',
'undefined': 'grey',
'null': 'bold',
'string': 'green',
'symbol': 'green',
'date': 'magenta',
// "name": intentionally not styling
'regexp': 'red'
};
inspect.styles = Object.assign(Object.create(null), styles);
If confirmed, I'd be happy to implement it.
Inspired by this StackOverflow question