summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRuben Bridgewater <ruben@bridgewater.de>2019-05-09 09:22:15 +0200
committerRuben Bridgewater <ruben@bridgewater.de>2019-05-20 14:18:18 +0200
commit5518664d41b8916dfbe2eca2180d760db632748e (patch)
tree38b36fd6e4ba56e5a0ef1a0955fc495270675144 /lib
parent182b48aa777a2c9c453f729c162412b6900b055d (diff)
downloadandroid-node-v8-5518664d41b8916dfbe2eca2180d760db632748e.tar.gz
android-node-v8-5518664d41b8916dfbe2eca2180d760db632748e.tar.bz2
android-node-v8-5518664d41b8916dfbe2eca2180d760db632748e.zip
util: if present, fallback to `toString` using the %s formatter
This makes sure that `util.format` uses `String` to stringify an object in case the object has an own property named `toString` with type `function`. That way objects that do not have such function are still inspected using `util.inspect` and the old behavior is preserved as well. PR-URL: https://github.com/nodejs/node/pull/27621 Refs: https://github.com/facebook/jest/issues/8443 Reviewed-By: Roman Reiss <me@silverwind.io>
Diffstat (limited to 'lib')
-rw-r--r--lib/internal/util/inspect.js39
1 files changed, 30 insertions, 9 deletions
diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js
index 07757f3fe0..e46a18633c 100644
--- a/lib/internal/util/inspect.js
+++ b/lib/internal/util/inspect.js
@@ -93,6 +93,10 @@ const { NativeModule } = require('internal/bootstrap/loaders');
let hexSlice;
+const builtInObjects = new Set(
+ Object.getOwnPropertyNames(global).filter((e) => /^([A-Z][a-z]+)+$/.test(e))
+);
+
const inspectDefaultOptions = Object.seal({
showHidden: false,
depth: 2,
@@ -1541,16 +1545,33 @@ function formatWithOptions(inspectOptions, ...args) {
switch (nextChar) {
case 115: // 's'
const tempArg = args[++a];
- if (typeof tempArg !== 'string' &&
- typeof tempArg !== 'function') {
- tempStr = inspect(tempArg, {
- ...inspectOptions,
- compact: 3,
- colors: false,
- depth: 0
- });
+ if (typeof tempArg === 'number') {
+ tempStr = formatNumber(stylizeNoColor, tempArg);
+ // eslint-disable-next-line valid-typeof
+ } else if (typeof tempArg === 'bigint') {
+ tempStr = `${tempArg}n`;
} else {
- tempStr = String(tempArg);
+ let constr;
+ if (typeof tempArg !== 'object' ||
+ tempArg === null ||
+ typeof tempArg.toString === 'function' &&
+ // A direct own property.
+ (hasOwnProperty(tempArg, 'toString') ||
+ // A direct own property on the constructor prototype in
+ // case the constructor is not an built-in object.
+ (constr = tempArg.constructor) &&
+ !builtInObjects.has(constr.name) &&
+ constr.prototype &&
+ hasOwnProperty(constr.prototype, 'toString'))) {
+ tempStr = String(tempArg);
+ } else {
+ tempStr = inspect(tempArg, {
+ ...inspectOptions,
+ compact: 3,
+ colors: false,
+ depth: 0
+ });
+ }
}
break;
case 106: // 'j'