Skip to content

Commit 0deef2d

Browse files
Chenyu Yangtargos
Chenyu Yang
authored andcommitted
util: fix %s format behavior with Symbol.toPrimitive
This commit ensures `console.log("%s", obj)` correctly invokes `obj[Symbol.toPrimitive]` for string conversion, fixing unexpected object display issue. PR-URL: #50992 Fixes: #50909 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Zeyu "Alex" Yang <himself65@outlook.com>
1 parent cd00cdc commit 0deef2d

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

lib/internal/util/inspect.js

+6
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ const {
8787
SymbolIterator,
8888
SymbolPrototypeToString,
8989
SymbolPrototypeValueOf,
90+
SymbolToPrimitive,
9091
SymbolToStringTag,
9192
TypedArrayPrototypeGetLength,
9293
TypedArrayPrototypeGetSymbolToStringTag,
@@ -2103,6 +2104,11 @@ function hasBuiltInToString(value) {
21032104
value = proxyTarget;
21042105
}
21052106

2107+
// Check if value has a custom Symbol.toPrimitive transformation.
2108+
if (typeof value[SymbolToPrimitive] === 'function') {
2109+
return false;
2110+
}
2111+
21062112
// Count objects that have no `toString` function as built-in.
21072113
if (typeof value.toString !== 'function') {
21082114
return true;

test/parallel/test-util-format.js

+21
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,27 @@ assert.strictEqual(util.format('%s', -Infinity), '-Infinity');
269269
);
270270
}
271271

272+
// Symbol.toPrimitive handling for string format specifier
273+
{
274+
const objectWithToPrimitive = {
275+
[Symbol.toPrimitive](hint) {
276+
switch (hint) {
277+
case 'number':
278+
return 42;
279+
case 'string':
280+
return 'string representation';
281+
case 'default':
282+
default:
283+
return 'default context';
284+
}
285+
}
286+
};
287+
288+
assert.strictEqual(util.format('%s', +objectWithToPrimitive), '42');
289+
assert.strictEqual(util.format('%s', objectWithToPrimitive), 'string representation');
290+
assert.strictEqual(util.format('%s', objectWithToPrimitive + ''), 'default context');
291+
}
292+
272293
// JSON format specifier
273294
assert.strictEqual(util.format('%j'), '%j');
274295
assert.strictEqual(util.format('%j', 42), '42');

0 commit comments

Comments
 (0)