From 261412985f971bb43ea7fd6c9a076c2e3781ccd4 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Wed, 24 Sep 2025 10:48:22 -0400
Subject: [PATCH v6 1/7] Fix array allocation bugs in SetExplainExtensionState.

If we already have an extension_state array but see a new extension_id
much larger than the highest the extension_id we've previously seen,
the old code might have failed to expand the array to a large enough
size, leading to disaster. Also, if we don't have an extension array
at all and need to create one, we should make sure that it's big enough
that we don't have to resize it instantly.

Reported-by: Tom Lane <tgl@sss.pgh.pa.us>
---
 src/backend/commands/explain_state.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/backend/commands/explain_state.c b/src/backend/commands/explain_state.c
index 60d98d63a62..9fdeeab6436 100644
--- a/src/backend/commands/explain_state.c
+++ b/src/backend/commands/explain_state.c
@@ -281,7 +281,8 @@ SetExplainExtensionState(ExplainState *es, int extension_id, void *opaque)
 	/* If there is no array yet, create one. */
 	if (es->extension_state == NULL)
 	{
-		es->extension_state_allocated = 16;
+		es->extension_state_allocated =
+			Max(16, pg_nextpower2_32(extension_id + 1));
 		es->extension_state =
 			palloc0(es->extension_state_allocated * sizeof(void *));
 	}
@@ -291,7 +292,7 @@ SetExplainExtensionState(ExplainState *es, int extension_id, void *opaque)
 	{
 		int			i;
 
-		i = pg_nextpower2_32(es->extension_state_allocated + 1);
+		i = pg_nextpower2_32(extension_id + 1);
 		es->extension_state = (void **)
 			repalloc0(es->extension_state,
 					  es->extension_state_allocated * sizeof(void *),
-- 
2.39.5 (Apple Git-154)

