Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit cb0ccef

Browse files
committed
Detect more overflows in timestamp[tz]_pl_interval.
In commit 25cd2d6 I (tgl) opined that "The additions of the months and microseconds fields could also overflow, of course. However, I believe we need no additional checks there; the existing range checks should catch such cases". This is demonstrably wrong however for the microseconds field, and given that discovery it seems prudent to be paranoid about the months addition as well. Report and patch by Joseph Koshakow. As before, back-patch to all supported branches. (However, the test case doesn't work before v15 because we didn't allow wider-than-int32 numbers in interval literals. A variant test could probably be built that fits within that restriction, but it didn't seem worth the trouble.) Discussion: https://postgr.es/m/CAAvxfHf77sRHKoEzUw9_cMYSpbpNS2C+J_+8Dq4+0oi8iKopeA@mail.gmail.com
1 parent 6d4a170 commit cb0ccef

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

src/backend/utils/adt/timestamp.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,7 +2859,10 @@ timestamp_pl_interval(PG_FUNCTION_ARGS)
28592859
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
28602860
errmsg("timestamp out of range")));
28612861

2862-
tm->tm_mon += span->month;
2862+
if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
2863+
ereport(ERROR,
2864+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2865+
errmsg("timestamp out of range")));
28632866
if (tm->tm_mon > MONTHS_PER_YEAR)
28642867
{
28652868
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
@@ -2911,7 +2914,10 @@ timestamp_pl_interval(PG_FUNCTION_ARGS)
29112914
errmsg("timestamp out of range")));
29122915
}
29132916

2914-
timestamp += span->time;
2917+
if (pg_add_s64_overflow(timestamp, span->time, &timestamp))
2918+
ereport(ERROR,
2919+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2920+
errmsg("timestamp out of range")));
29152921

29162922
if (!IS_VALID_TIMESTAMP(timestamp))
29172923
ereport(ERROR,
@@ -2973,7 +2979,10 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
29732979
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
29742980
errmsg("timestamp out of range")));
29752981

2976-
tm->tm_mon += span->month;
2982+
if (pg_add_s32_overflow(tm->tm_mon, span->month, &tm->tm_mon))
2983+
ereport(ERROR,
2984+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
2985+
errmsg("timestamp out of range")));
29772986
if (tm->tm_mon > MONTHS_PER_YEAR)
29782987
{
29792988
tm->tm_year += (tm->tm_mon - 1) / MONTHS_PER_YEAR;
@@ -3032,7 +3041,10 @@ timestamptz_pl_interval(PG_FUNCTION_ARGS)
30323041
errmsg("timestamp out of range")));
30333042
}
30343043

3035-
timestamp += span->time;
3044+
if (pg_add_s64_overflow(timestamp, span->time, &timestamp))
3045+
ereport(ERROR,
3046+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
3047+
errmsg("timestamp out of range")));
30363048

30373049
if (!IS_VALID_TIMESTAMP(timestamp))
30383050
ereport(ERROR,

0 commit comments

Comments
 (0)