From 2748c01a3e343001d3668554fdb7ee894fefbdf1 Mon Sep 17 00:00:00 2001
From: Laurenz Albe <laurenz.albe@cybertec.at>
Date: Wed, 15 Nov 2023 18:21:42 +0100
Subject: [PATCH] Check for overflow in interval division

Dividing a large interval by a small floating point number
can lead to integer overflow, which results in bogus values.
Report by Alexander Lakhin.

Discussion: https://postgr.es/m/18200-5ea288c7b2d504b1@postgresql.org
---
 src/backend/utils/adt/timestamp.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 647b97aca6..b21efeb897 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -3422,6 +3422,15 @@ interval_div(PG_FUNCTION_ARGS)
 				(errcode(ERRCODE_DIVISION_BY_ZERO),
 				 errmsg("division by zero")));
 
+	/* check for overflow */
+	if (span->month / factor > PG_INT32_MAX ||
+		span->month / factor < PG_INT32_MIN ||
+		span->day / factor > PG_INT32_MAX ||
+		span->day / factor < PG_INT32_MIN)
+	ereport(ERROR,
+			errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+			errmsg("interval out of range"));
+
 	result->month = (int32) (span->month / factor);
 	result->day = (int32) (span->day / factor);
 
-- 
2.41.0

