From ef1219a7e97525a42a21bc27f982fd9e2e9a2c30 Mon Sep 17 00:00:00 2001
From: Varik Matevosyan <varikmatevosyan@gmail.com>
Date: Mon, 4 May 2026 10:53:05 +0000
Subject: [PATCH] contrib/xml2: guard against signed integer overflow in
 parse_params

The doubling of max_params in parse_params relies on signed integer
overflow to wrap to a negative value that AllocSizeIsValid then
rejects, producing a clean ereport. This is incidental safety:
signed overflow is undefined per the C standard, and the graceful
ERROR depends on the wrapped value falling outside MaxAllocSize
after promotion to size_t.

In current builds the overflow is unreachable, since text input is
bounded by MaxAllocSize and that limits nparams below the doubling
threshold. Guard the multiplication anyway, matching the explicit
overflow-checking idiom used elsewhere in the tree.
---
 contrib/xml2/xslt_proc.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/contrib/xml2/xslt_proc.c b/contrib/xml2/xslt_proc.c
index 8ceb8c46494..39116118663 100644
--- a/contrib/xml2/xslt_proc.c
+++ b/contrib/xml2/xslt_proc.c
@@ -7,6 +7,7 @@
  */
 #include "postgres.h"
 
+#include "common/int.h"
 #include "fmgr.h"
 #include "utils/builtins.h"
 #include "utils/xml.h"
@@ -216,6 +217,7 @@ parse_params(text *paramstr)
 	char	   *itsep = ",";
 	const char **params;
 	int			max_params;
+	int			new_max_params;
 	int			nparams;
 
 	pstr = text_to_cstring(paramstr);
@@ -230,7 +232,12 @@ parse_params(text *paramstr)
 	{
 		if (nparams >= max_params)
 		{
-			max_params *= 2;
+			if (pg_mul_s32_overflow(max_params, 2, &new_max_params))
+				ereport(ERROR,
+						(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+						 errmsg("too many XSLT parameters")));
+
+			max_params = new_max_params;
 			params = (const char **) repalloc(params,
 											  (max_params + 1) * sizeof(char *));
 		}
-- 
2.43.0

