From 371a726043074b7c3f86c47107e38ab1f5462ed8 Mon Sep 17 00:00:00 2001 From: Osamaali313 Date: Tue, 11 Aug 2026 22:44:45 +0300 Subject: [PATCH] fix: message-parser timestamps overflow for dates from 2038 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `` timestamps parsed the epoch seconds with `(... / 1000) | 0`. The `| 0` coerces to a signed 32-bit integer, so any date at or after 2038-01-19 03:14:07 UTC wraps to a negative value — e.g. `` became -2085978496, which the renderer shows as a 1903 date instead of 2040. Use `Math.floor` instead of `| 0` in both `timestampFromIsoTime` and the sibling `timestampFromHours`. For all in-range dates the result is identical (the inputs are non-negative, so floor and truncation agree), so this only fixes the overflow. Added a regression test past the 2038 boundary. --- .changeset/fix-message-parser-timestamp-overflow.md | 5 +++++ packages/message-parser/src/utils.ts | 10 +++++----- packages/message-parser/tests/timestamp.test.ts | 3 +++ 3 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .changeset/fix-message-parser-timestamp-overflow.md diff --git a/.changeset/fix-message-parser-timestamp-overflow.md b/.changeset/fix-message-parser-timestamp-overflow.md new file mode 100644 index 0000000000000..0a6feb3890b01 --- /dev/null +++ b/.changeset/fix-message-parser-timestamp-overflow.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/message-parser': patch +--- + +Fixes `` timestamps with dates on or after 2038-01-19 rendering as a wrong (1903) date. The parser truncated the epoch seconds with `| 0`, which overflows the 32-bit signed range; it now uses `Math.floor`, so future dates parse correctly. diff --git a/packages/message-parser/src/utils.ts b/packages/message-parser/src/utils.ts index 8fa65001c76f1..516cbe7dc51ac 100644 --- a/packages/message-parser/src/utils.ts +++ b/packages/message-parser/src/utils.ts @@ -363,7 +363,7 @@ export const timestampFromHours = (hours: string, minutes = '00', seconds = '00' const yearMonthDay = date.toISOString().split('T')[0]; - const timestamp = (new Date(`${yearMonthDay}T${hours}:${minutes}:${seconds}${timezone}`).getTime() / 1000) | 0; + const timestamp = Math.floor(new Date(`${yearMonthDay}T${hours}:${minutes}:${seconds}${timezone}`).getTime() / 1000); return timestamp.toString(); }; @@ -387,9 +387,9 @@ export const timestampFromIsoTime = ({ milliseconds?: string; timezone?: string; }) => { - const date = - (new Date(`${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds || '000'}${timezone ? `${timezone}` : ''}`).getTime() / - 1000) | - 0; + const date = Math.floor( + new Date(`${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds || '000'}${timezone ? `${timezone}` : ''}`).getTime() / + 1000, + ); return date.toString(); }; diff --git a/packages/message-parser/tests/timestamp.test.ts b/packages/message-parser/tests/timestamp.test.ts index 6e6eab6ccab32..c177e690082f9 100644 --- a/packages/message-parser/tests/timestamp.test.ts +++ b/packages/message-parser/tests/timestamp.test.ts @@ -53,6 +53,9 @@ test.each([ ['', '1753178400', 'R' as const], ['', '1753178400', 'R' as const], ['', '1753388398', 'R' as const], + // Beyond the 2038-01-19 32-bit boundary: must not overflow to a negative + // (previously `| 0` turned this into -2085978496 -> a 1903 date). + ['', '2208988800', 'R' as const], ])('parses %p', (input, value, format) => { const node = timestampNode(value, format, [0, input.length]); expect(parse(input)).toEqual([paragraph([node])]);