From ff53ef5e3751fc0e9ba4b9a327e65df2c02de411 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 26 May 2025 15:23:32 -0400
Subject: [PATCH v4 5/5] Avoid leak when dblink_connstr_check() fails.

dblink_connect() leaked the already-allocated remoteConn struct
in this case.  We can improve matters by just doing that allocation
a bit later.  There remain leakage opportunities, such as OOM
inside createNewConnection(), but at least they're not reached
while valgrind'ing the regression tests.

Author: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/2976982.1748049023@sss.pgh.pa.us
---
 contrib/dblink/dblink.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 1e1baf68635..5347bf74087 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -288,15 +288,6 @@ dblink_connect(PG_FUNCTION_ARGS)
 	else if (PG_NARGS() == 1)
 		conname_or_str = text_to_cstring(PG_GETARG_TEXT_PP(0));
 
-	if (connname)
-	{
-		rconn = (remoteConn *) MemoryContextAlloc(TopMemoryContext,
-												  sizeof(remoteConn));
-		rconn->conn = NULL;
-		rconn->openCursorCount = 0;
-		rconn->newXactForCursor = false;
-	}
-
 	/* first check for valid foreign data server */
 	connstr = get_connect_string(conname_or_str);
 	if (connstr == NULL)
@@ -309,6 +300,16 @@ dblink_connect(PG_FUNCTION_ARGS)
 	if (dblink_we_connect == 0)
 		dblink_we_connect = WaitEventExtensionNew("DblinkConnect");
 
+	/* allocate rconn, if needed, as late as possible */
+	if (connname)
+	{
+		rconn = (remoteConn *) MemoryContextAlloc(TopMemoryContext,
+												  sizeof(remoteConn));
+		rconn->conn = NULL;
+		rconn->openCursorCount = 0;
+		rconn->newXactForCursor = false;
+	}
+
 	/* OK to make connection */
 	conn = libpqsrv_connect(connstr, dblink_we_connect);
 
-- 
2.43.5

