diff options
author | Dean Rasheed <dean.a.rasheed@gmail.com> | 2023-11-09 12:10:14 +0000 |
---|---|---|
committer | Dean Rasheed <dean.a.rasheed@gmail.com> | 2023-11-09 12:10:14 +0000 |
commit | 3850d4dec1d91c4fdce274f42986840444d5593e (patch) | |
tree | 0a9284641c901c15d11fe5329dd3530369a9ddac /src/backend/utils/adt/date.c | |
parent | a4f7d33a904fcd4da7a12d249416dd2c5c5f2c1c (diff) |
Avoid integer overflow hazard in interval_time().
When casting an interval to a time, the original code suffered from
64-bit integer overflow for inputs with a sufficiently large negative
"time" field, leading to bogus results.
Fix by rewriting the algorithm in a simpler form, that more obviously
cannot overflow. While at it, improve the test coverage to include
negative interval inputs.
Discussion: https://postgr.es/m/CAEZATCXoUKHkcuq4q63hkiPsKZJd0kZWzgKtU%2BNT0aU4wbf_Pw%40mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/date.c')
-rw-r--r-- | src/backend/utils/adt/date.c | 15 |
1 files changed, 3 insertions, 12 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index 56c7746c11f..544e1d32bfc 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -2012,19 +2012,10 @@ interval_time(PG_FUNCTION_ARGS) { Interval *span = PG_GETARG_INTERVAL_P(0); TimeADT result; - int64 days; - result = span->time; - if (result >= USECS_PER_DAY) - { - days = result / USECS_PER_DAY; - result -= days * USECS_PER_DAY; - } - else if (result < 0) - { - days = (-result + USECS_PER_DAY - 1) / USECS_PER_DAY; - result += days * USECS_PER_DAY; - } + result = span->time % USECS_PER_DAY; + if (result < 0) + result += USECS_PER_DAY; PG_RETURN_TIMEADT(result); } |