8eda8a
This patch was created based on upstream commit:
8eda8a
https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=18b585155a891784ca8985f595ebc0dde94e0d43
8eda8a
8eda8a
The upstream regression test is not applicable for PG9.2
8eda8a
8eda8a
int.h source file comes from:
8eda8a
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/common/int.h;h=487124473d25b206a985a9742f39b348f50a5324
8eda8a
8eda8a
diff -urN -x '*cscope*' postgresql-9.2.24/src/backend/utils/adt/arrayfuncs.c postgresql-final/src/backend/utils/adt/arrayfuncs.c
8eda8a
--- postgresql-9.2.24/src/backend/utils/adt/arrayfuncs.c	2017-11-06 23:17:39.000000000 +0100
8eda8a
+++ postgresql-final/src/backend/utils/adt/arrayfuncs.c	2023-11-21 15:20:49.000000000 +0100
8eda8a
@@ -24,7 +24,7 @@
8eda8a
 #include "utils/lsyscache.h"
8eda8a
 #include "utils/memutils.h"
8eda8a
 #include "utils/typcache.h"
8eda8a
-
8eda8a
+#include "common/int.h"
8eda8a
 
8eda8a
 /*
8eda8a
  * GUC parameter
8eda8a
@@ -2138,22 +2138,38 @@
8eda8a
 	addedbefore = addedafter = 0;
8eda8a
 
8eda8a
 	/*
8eda8a
-	 * Check subscripts
8eda8a
+	 * Check subscripts.  We assume the existing subscripts passed
8eda8a
+	 * ArrayCheckBounds, so that dim[i] + lb[i] can be computed without
8eda8a
+	 * overflow.  But we must beware of other overflows in our calculations of
8eda8a
+	 * new dim[] values.
8eda8a
 	 */
8eda8a
 	if (ndim == 1)
8eda8a
 	{
8eda8a
 		if (indx[0] < lb[0])
8eda8a
 		{
8eda8a
-			addedbefore = lb[0] - indx[0];
8eda8a
-			dim[0] += addedbefore;
8eda8a
+			// addedbefore = lb[0] - indx[0];
8eda8a
+			// dim[0] += addedbefore;
8eda8a
+			if (pg_sub_s32_overflow(lb[0], indx[0], &addedbefore) ||
8eda8a
+		        	pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
8eda8a
+               			ereport(ERROR,
8eda8a
+                       			(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
8eda8a
+                        		errmsg("array size exceeds the maximum allowed (%d)",
8eda8a
+                               			(int) MaxArraySize)));
8eda8a
 			lb[0] = indx[0];
8eda8a
 			if (addedbefore > 1)
8eda8a
 				newhasnulls = true;		/* will insert nulls */
8eda8a
 		}
8eda8a
 		if (indx[0] >= (dim[0] + lb[0]))
8eda8a
 		{
8eda8a
-			addedafter = indx[0] - (dim[0] + lb[0]) + 1;
8eda8a
-			dim[0] += addedafter;
8eda8a
+			// addedafter = indx[0] - (dim[0] + lb[0]) + 1;
8eda8a
+			// dim[0] += addedafter;
8eda8a
+			if (pg_sub_s32_overflow(indx[0], dim[0] + lb[0], &addedafter) ||
8eda8a
+			    pg_add_s32_overflow(addedafter, 1, &addedafter) ||
8eda8a
+               		    pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
8eda8a
+               		    ereport(ERROR,
8eda8a
+                       		    (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
8eda8a
+                        	    errmsg("array size exceeds the maximum allowed (%d)",
8eda8a
+                               		   (int) MaxArraySize)));
8eda8a
 			if (addedafter > 1)
8eda8a
 				newhasnulls = true;		/* will insert nulls */
8eda8a
 		}
8eda8a
@@ -2435,18 +2451,31 @@
8eda8a
 					 errmsg("upper bound cannot be less than lower bound")));
8eda8a
 		if (lowerIndx[0] < lb[0])
8eda8a
 		{
8eda8a
-			if (upperIndx[0] < lb[0] - 1)
8eda8a
-				newhasnulls = true;		/* will insert nulls */
8eda8a
-			addedbefore = lb[0] - lowerIndx[0];
8eda8a
-			dim[0] += addedbefore;
8eda8a
+			// addedbefore = lb[0] - lowerIndx[0];
8eda8a
+			// dim[0] += addedbefore;
8eda8a
+			if (pg_sub_s32_overflow(lb[0], lowerIndx[0], &addedbefore) ||
8eda8a
+	                    pg_add_s32_overflow(dim[0], addedbefore, &dim[0]))
8eda8a
+	               	    ereport(ERROR,
8eda8a
+	                            (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
8eda8a
+            		             errmsg("array size exceeds the maximum allowed (%d)",
8eda8a
+	                                     (int) MaxArraySize)));
8eda8a
 			lb[0] = lowerIndx[0];
8eda8a
+			if (addedbefore > 1)
8eda8a
+				newhasnulls = true;		/* will insert nulls */
8eda8a
 		}
8eda8a
 		if (upperIndx[0] >= (dim[0] + lb[0]))
8eda8a
 		{
8eda8a
-			if (lowerIndx[0] > (dim[0] + lb[0]))
8eda8a
+			if (pg_sub_s32_overflow(upperIndx[0], dim[0] + lb[0], &addedafter) ||
8eda8a
+		            pg_add_s32_overflow(addedafter, 1, &addedafter) ||
8eda8a
+		            pg_add_s32_overflow(dim[0], addedafter, &dim[0]))
8eda8a
+		            ereport(ERROR,
8eda8a
+				    (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
8eda8a
+				     errmsg("array size exceeds the maximum allowed (%d)",
8eda8a
+                                            (int) MaxArraySize)));
8eda8a
+			if (addedafter > 1)
8eda8a
 				newhasnulls = true;		/* will insert nulls */
8eda8a
-			addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
8eda8a
-			dim[0] += addedafter;
8eda8a
+			// addedafter = upperIndx[0] - (dim[0] + lb[0]) + 1;
8eda8a
+			// dim[0] += addedafter;
8eda8a
 		}
8eda8a
 	}
8eda8a
 	else
8eda8a
diff -urN -x '*cscope*' postgresql-9.2.24/src/backend/utils/adt/arrayutils.c postgresql-final/src/backend/utils/adt/arrayutils.c
8eda8a
--- postgresql-9.2.24/src/backend/utils/adt/arrayutils.c	2017-11-06 23:17:39.000000000 +0100
8eda8a
+++ postgresql-final/src/backend/utils/adt/arrayutils.c	2023-11-21 15:19:25.000000000 +0100
8eda8a
@@ -63,10 +63,6 @@
8eda8a
  * This must do overflow checking, since it is used to validate that a user
8eda8a
  * dimensionality request doesn't overflow what we can handle.
8eda8a
  *
8eda8a
- * We limit array sizes to at most about a quarter billion elements,
8eda8a
- * so that it's not necessary to check for overflow in quite so many
8eda8a
- * places --- for instance when palloc'ing Datum arrays.
8eda8a
- *
8eda8a
  * The multiplication overflow check only works on machines that have int64
8eda8a
  * arithmetic, but that is nearly all platforms these days, and doing check
8eda8a
  * divides for those that don't seems way too expensive.
8eda8a
@@ -77,7 +73,6 @@
8eda8a
 	int32		ret;
8eda8a
 	int			i;
8eda8a
 
8eda8a
-#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
8eda8a
 
8eda8a
 	if (ndim <= 0)
8eda8a
 		return 0;
8eda8a
diff -urN -x '*cscope*' postgresql-9.2.24/src/include/c.h postgresql-final/src/include/c.h
8eda8a
--- postgresql-9.2.24/src/include/c.h	2017-11-06 23:17:39.000000000 +0100
8eda8a
+++ postgresql-final/src/include/c.h	2023-11-21 15:19:25.000000000 +0100
8eda8a
@@ -215,6 +215,23 @@
8eda8a
  */
8eda8a
 
8eda8a
 /*
8eda8a
+ * stdint.h limits aren't guaranteed to be present and aren't guaranteed to
8eda8a
+ * have compatible types with our fixed width types. So just define our own.
8eda8a
+ */
8eda8a
+#define PG_INT8_MIN             (-0x7F-1)
8eda8a
+#define PG_INT8_MAX             (0x7F)
8eda8a
+#define PG_UINT8_MAX    (0xFF)
8eda8a
+#define PG_INT16_MIN    (-0x7FFF-1)
8eda8a
+#define PG_INT16_MAX    (0x7FFF)
8eda8a
+#define PG_UINT16_MAX   (0xFFFF)
8eda8a
+#define PG_INT32_MIN    (-0x7FFFFFFF-1)
8eda8a
+#define PG_INT32_MAX    (0x7FFFFFFF)
8eda8a
+#define PG_UINT32_MAX   (0xFFFFFFFFU)
8eda8a
+#define PG_INT64_MIN    (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1)
8eda8a
+#define PG_INT64_MAX    INT64CONST(0x7FFFFFFFFFFFFFFF)
8eda8a
+#define PG_UINT64_MAX   UINT64CONST(0xFFFFFFFFFFFFFFFF)
8eda8a
+
8eda8a
+/*
8eda8a
  * Pointer
8eda8a
  *		Variable holding address of any memory resident object.
8eda8a
  *
8eda8a
diff -urN -x '*cscope*' postgresql-9.2.24/src/include/common/int.h postgresql-final/src/include/common/int.h
8eda8a
--- postgresql-9.2.24/src/include/common/int.h	1970-01-01 01:00:00.000000000 +0100
8eda8a
+++ postgresql-final/src/include/common/int.h	2023-11-21 15:19:25.000000000 +0100
8eda8a
@@ -0,0 +1,441 @@
8eda8a
+/*-------------------------------------------------------------------------
8eda8a
+ *
8eda8a
+ * int.h
8eda8a
+ *	  Routines to perform integer math, while checking for overflows.
8eda8a
+ *
8eda8a
+ * The routines in this file are intended to be well defined C, without
8eda8a
+ * relying on compiler flags like -fwrapv.
8eda8a
+ *
8eda8a
+ * To reduce the overhead of these routines try to use compiler intrinsics
8eda8a
+ * where available. That's not that important for the 16, 32 bit cases, but
8eda8a
+ * the 64 bit cases can be considerably faster with intrinsics. In case no
8eda8a
+ * intrinsics are available 128 bit math is used where available.
8eda8a
+ *
8eda8a
+ * Copyright (c) 2017-2023, PostgreSQL Global Development Group
8eda8a
+ *
8eda8a
+ * src/include/common/int.h
8eda8a
+ *
8eda8a
+ *-------------------------------------------------------------------------
8eda8a
+ */
8eda8a
+#ifndef COMMON_INT_H
8eda8a
+#define COMMON_INT_H
8eda8a
+
8eda8a
+
8eda8a
+/*---------
8eda8a
+ * The following guidelines apply to all the routines:
8eda8a
+ * - If a + b overflows, return true, otherwise store the result of a + b
8eda8a
+ * into *result. The content of *result is implementation defined in case of
8eda8a
+ * overflow.
8eda8a
+ * - If a - b overflows, return true, otherwise store the result of a - b
8eda8a
+ * into *result. The content of *result is implementation defined in case of
8eda8a
+ * overflow.
8eda8a
+ * - If a * b overflows, return true, otherwise store the result of a * b
8eda8a
+ * into *result. The content of *result is implementation defined in case of
8eda8a
+ * overflow.
8eda8a
+ *---------
8eda8a
+ */
8eda8a
+
8eda8a
+/*------------------------------------------------------------------------
8eda8a
+ * Overflow routines for signed integers
8eda8a
+ *------------------------------------------------------------------------
8eda8a
+ */
8eda8a
+
8eda8a
+/*
8eda8a
+ * INT16
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_s16_overflow(int16 a, int16 b, int16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int32		res = (int32) a + (int32) b;
8eda8a
+
8eda8a
+	if (res > PG_INT16_MAX || res < PG_INT16_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int16) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_s16_overflow(int16 a, int16 b, int16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int32		res = (int32) a - (int32) b;
8eda8a
+
8eda8a
+	if (res > PG_INT16_MAX || res < PG_INT16_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int16) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_s16_overflow(int16 a, int16 b, int16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int32		res = (int32) a * (int32) b;
8eda8a
+
8eda8a
+	if (res > PG_INT16_MAX || res < PG_INT16_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int16) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+/*
8eda8a
+ * INT32
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_s32_overflow(int32 a, int32 b, int32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int64		res = (int64) a + (int64) b;
8eda8a
+
8eda8a
+	if (res > PG_INT32_MAX || res < PG_INT32_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int32) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_s32_overflow(int32 a, int32 b, int32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int64		res = (int64) a - (int64) b;
8eda8a
+
8eda8a
+	if (res > PG_INT32_MAX || res < PG_INT32_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int32) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_s32_overflow(int32 a, int32 b, int32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	int64		res = (int64) a * (int64) b;
8eda8a
+
8eda8a
+	if (res > PG_INT32_MAX || res < PG_INT32_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int32) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+/*
8eda8a
+ * INT64
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_s64_overflow(int64 a, int64 b, int64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#elif defined(HAVE_INT128)
8eda8a
+	int128		res = (int128) a + (int128) b;
8eda8a
+
8eda8a
+	if (res > PG_INT64_MAX || res < PG_INT64_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int64) res;
8eda8a
+	return false;
8eda8a
+#else
8eda8a
+	if ((a > 0 && b > 0 && a > PG_INT64_MAX - b) ||
8eda8a
+		(a < 0 && b < 0 && a < PG_INT64_MIN - b))
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a + b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#elif defined(HAVE_INT128)
8eda8a
+	int128		res = (int128) a - (int128) b;
8eda8a
+
8eda8a
+	if (res > PG_INT64_MAX || res < PG_INT64_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int64) res;
8eda8a
+	return false;
8eda8a
+#else
8eda8a
+	/*
8eda8a
+	 * Note: overflow is also possible when a == 0 and b < 0 (specifically,
8eda8a
+	 * when b == PG_INT64_MIN).
8eda8a
+	 */
8eda8a
+	if ((a < 0 && b > 0 && a < PG_INT64_MIN + b) ||
8eda8a
+		(a >= 0 && b < 0 && a > PG_INT64_MAX + b))
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a - b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#elif defined(HAVE_INT128)
8eda8a
+	int128		res = (int128) a * (int128) b;
8eda8a
+
8eda8a
+	if (res > PG_INT64_MAX || res < PG_INT64_MIN)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (int64) res;
8eda8a
+	return false;
8eda8a
+#else
8eda8a
+	/*
8eda8a
+	 * Overflow can only happen if at least one value is outside the range
8eda8a
+	 * sqrt(min)..sqrt(max) so check that first as the division can be quite a
8eda8a
+	 * bit more expensive than the multiplication.
8eda8a
+	 *
8eda8a
+	 * Multiplying by 0 or 1 can't overflow of course and checking for 0
8eda8a
+	 * separately avoids any risk of dividing by 0.  Be careful about dividing
8eda8a
+	 * INT_MIN by -1 also, note reversing the a and b to ensure we're always
8eda8a
+	 * dividing it by a positive value.
8eda8a
+	 *
8eda8a
+	 */
8eda8a
+	if ((a > PG_INT32_MAX || a < PG_INT32_MIN ||
8eda8a
+		 b > PG_INT32_MAX || b < PG_INT32_MIN) &&
8eda8a
+		a != 0 && a != 1 && b != 0 && b != 1 &&
8eda8a
+		((a > 0 && b > 0 && a > PG_INT64_MAX / b) ||
8eda8a
+		 (a > 0 && b < 0 && b < PG_INT64_MIN / a) ||
8eda8a
+		 (a < 0 && b > 0 && a < PG_INT64_MIN / b) ||
8eda8a
+		 (a < 0 && b < 0 && a < PG_INT64_MAX / b)))
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a * b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+/*------------------------------------------------------------------------
8eda8a
+ * Overflow routines for unsigned integers
8eda8a
+ *------------------------------------------------------------------------
8eda8a
+ */
8eda8a
+
8eda8a
+/*
8eda8a
+ * UINT16
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_u16_overflow(uint16 a, uint16 b, uint16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	uint16		res = a + b;
8eda8a
+
8eda8a
+	if (res < a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_u16_overflow(uint16 a, uint16 b, uint16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	if (b > a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a - b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_u16_overflow(uint16 a, uint16 b, uint16 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	uint32		res = (uint32) a * (uint32) b;
8eda8a
+
8eda8a
+	if (res > PG_UINT16_MAX)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (uint16) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+/*
8eda8a
+ * INT32
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_u32_overflow(uint32 a, uint32 b, uint32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	uint32		res = a + b;
8eda8a
+
8eda8a
+	if (res < a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_u32_overflow(uint32 a, uint32 b, uint32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	if (b > a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a - b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_u32_overflow(uint32 a, uint32 b, uint32 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	uint64		res = (uint64) a * (uint64) b;
8eda8a
+
8eda8a
+	if (res > PG_UINT32_MAX)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (uint32) res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+/*
8eda8a
+ * UINT64
8eda8a
+ */
8eda8a
+static inline bool
8eda8a
+pg_add_u64_overflow(uint64 a, uint64 b, uint64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_add_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	uint64		res = a + b;
8eda8a
+
8eda8a
+	if (res < a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_sub_u64_overflow(uint64 a, uint64 b, uint64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_sub_overflow(a, b, result);
8eda8a
+#else
8eda8a
+	if (b > a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = a - b;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+static inline bool
8eda8a
+pg_mul_u64_overflow(uint64 a, uint64 b, uint64 *result)
8eda8a
+{
8eda8a
+#if defined(HAVE__BUILTIN_OP_OVERFLOW)
8eda8a
+	return __builtin_mul_overflow(a, b, result);
8eda8a
+#elif defined(HAVE_INT128)
8eda8a
+	uint128		res = (uint128) a * (uint128) b;
8eda8a
+
8eda8a
+	if (res > PG_UINT64_MAX)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = (uint64) res;
8eda8a
+	return false;
8eda8a
+#else
8eda8a
+	uint64		res = a * b;
8eda8a
+
8eda8a
+	if (a != 0 && b != res / a)
8eda8a
+	{
8eda8a
+		*result = 0x5EED;		/* to avoid spurious warnings */
8eda8a
+		return true;
8eda8a
+	}
8eda8a
+	*result = res;
8eda8a
+	return false;
8eda8a
+#endif
8eda8a
+}
8eda8a
+
8eda8a
+#endif							/* COMMON_INT_H */
8eda8a
diff -urN -x '*cscope*' postgresql-9.2.24/src/include/utils/array.h postgresql-final/src/include/utils/array.h
8eda8a
--- postgresql-9.2.24/src/include/utils/array.h	2017-11-06 23:17:39.000000000 +0100
8eda8a
+++ postgresql-final/src/include/utils/array.h	2023-11-21 15:19:25.000000000 +0100
8eda8a
@@ -59,6 +59,14 @@
8eda8a
 #include "fmgr.h"
8eda8a
 
8eda8a
 /*
8eda8a
+* Maximum number of elements in an array.  We limit this to at most about a
8eda8a
+* quarter billion elements, so that it's not necessary to check for overflow
8eda8a
+* in quite so many places --- for instance when palloc'ing Datum arrays.
8eda8a
+*/
8eda8a
+#define MaxArraySize ((Size) (MaxAllocSize / sizeof(Datum)))
8eda8a
+
8eda8a
+
8eda8a
+/*
8eda8a
  * Arrays are varlena objects, so must meet the varlena convention that
8eda8a
  * the first int32 of the object contains the total object size in bytes.
8eda8a
  * Be sure to use VARSIZE() and SET_VARSIZE() to access it, though!