Skip to content

Commit 2e6e4cf

Browse files
antsmartianaddaleax
authored andcommitted
util: add null prototype support for date
PR-URL: #25144 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 201a8d9 commit 2e6e4cf

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

lib/internal/util/inspect.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ function uncurryThis(func) {
7777
const propertyIsEnumerable = uncurryThis(Object.prototype.propertyIsEnumerable);
7878
const regExpToString = uncurryThis(RegExp.prototype.toString);
7979
const dateToISOString = uncurryThis(Date.prototype.toISOString);
80+
const dateToString = uncurryThis(Date.prototype.toString);
8081
const errorToString = uncurryThis(Error.prototype.toString);
8182

8283
const bigIntValueOf = uncurryThis(BigInt.prototype.valueOf);
@@ -646,12 +647,15 @@ function formatRaw(ctx, value, recurseTimes, typedArray) {
646647
return ctx.stylize(base, 'regexp');
647648
} else if (isDate(value)) {
648649
// Make dates with properties first say the date
650+
base = Number.isNaN(dateGetTime(value)) ?
651+
dateToString(value) :
652+
dateToISOString(value);
653+
const prefix = getPrefix(constructor, tag, 'Date');
654+
if (prefix !== 'Date ')
655+
base = `${prefix}${base}`;
649656
if (keys.length === 0) {
650-
if (Number.isNaN(dateGetTime(value)))
651-
return ctx.stylize(String(value), 'date');
652-
return ctx.stylize(dateToISOString(value), 'date');
657+
return ctx.stylize(base, 'date');
653658
}
654-
base = dateToISOString(value);
655659
} else if (isError(value)) {
656660
// Make error with message first say the error.
657661
base = formatError(value);

test/parallel/test-assert-deep.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,16 @@ assert.throws(
117117
{
118118
code: 'ERR_ASSERTION',
119119
message: `${defaultMsgStartFull}\n\n` +
120-
'+ 2016-01-01T00:00:00.000Z\n- 2016-01-01T00:00:00.000Z {\n' +
121-
"- '0': '1'\n- }"
120+
'+ 2016-01-01T00:00:00.000Z\n- MyDate 2016-01-01T00:00:00.000Z' +
121+
" {\n- '0': '1'\n- }"
122122
}
123123
);
124124
assert.throws(
125125
() => assert.deepStrictEqual(date2, date),
126126
{
127127
code: 'ERR_ASSERTION',
128128
message: `${defaultMsgStartFull}\n\n` +
129-
'+ 2016-01-01T00:00:00.000Z {\n' +
129+
'+ MyDate 2016-01-01T00:00:00.000Z {\n' +
130130
"+ '0': '1'\n+ }\n- 2016-01-01T00:00:00.000Z"
131131
}
132132
);

test/parallel/test-util-inspect.js

+47-1
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,9 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
16631663
'byteOffset: undefined,\n buffer: undefined }'],
16641664
[new SharedArrayBuffer(2), '[SharedArrayBuffer: null prototype] ' +
16651665
'{ [Uint8Contents]: <00 00>, byteLength: undefined }'],
1666-
[/foobar/, '[RegExp: null prototype] /foobar/']
1666+
[/foobar/, '[RegExp: null prototype] /foobar/'],
1667+
[new Date('Sun, 14 Feb 2010 11:48:40 GMT'),
1668+
'[Date: null prototype] 2010-02-14T11:48:40.000Z']
16671669
].forEach(([value, expected]) => {
16681670
assert.strictEqual(
16691671
util.inspect(Object.setPrototypeOf(value, null)),
@@ -1707,6 +1709,50 @@ assert.strictEqual(util.inspect('"\'${a}'), "'\"\\'${a}'");
17071709
assert(/\[Symbol\(foo\)]: 'yeah'/.test(res), res);
17081710
});
17091711

1712+
// Date null prototype checks
1713+
{
1714+
class CustomDate extends Date {
1715+
}
1716+
1717+
const date = new CustomDate('Sun, 14 Feb 2010 11:48:40 GMT');
1718+
assert.strictEqual(util.inspect(date), 'CustomDate 2010-02-14T11:48:40.000Z');
1719+
1720+
// add properties
1721+
date.foo = 'bar';
1722+
assert.strictEqual(util.inspect(date),
1723+
'{ CustomDate 2010-02-14T11:48:40.000Z foo: \'bar\' }');
1724+
1725+
// check for null prototype
1726+
Object.setPrototypeOf(date, null);
1727+
assert.strictEqual(util.inspect(date),
1728+
'{ [Date: null prototype] 2010-02-14T11:48:40.000Z' +
1729+
' foo: \'bar\' }');
1730+
1731+
const anotherDate = new CustomDate('Sun, 14 Feb 2010 11:48:40 GMT');
1732+
Object.setPrototypeOf(anotherDate, null);
1733+
assert.strictEqual(util.inspect(anotherDate),
1734+
'[Date: null prototype] 2010-02-14T11:48:40.000Z');
1735+
}
1736+
1737+
// Check for invalid dates and null prototype
1738+
{
1739+
class CustomDate extends Date {
1740+
}
1741+
1742+
const date = new CustomDate('invalid_date');
1743+
assert.strictEqual(util.inspect(date), 'CustomDate Invalid Date');
1744+
1745+
// add properties
1746+
date.foo = 'bar';
1747+
assert.strictEqual(util.inspect(date),
1748+
'{ CustomDate Invalid Date foo: \'bar\' }');
1749+
1750+
// check for null prototype
1751+
Object.setPrototypeOf(date, null);
1752+
assert.strictEqual(util.inspect(date),
1753+
'{ [Date: null prototype] Invalid Date foo: \'bar\' }');
1754+
}
1755+
17101756
assert.strictEqual(inspect(1n), '1n');
17111757
assert.strictEqual(inspect(Object(-1n)), '[BigInt: -1n]');
17121758
assert.strictEqual(inspect(Object(13n)), '[BigInt: 13n]');

0 commit comments

Comments
 (0)