From faea3db958074dcab74e03b882c9586f12a903fb Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 13 Jul 2005 15:25:55 +0000 Subject: [PATCH] Fix libpq memory leak during PQreset() --- closePGconn() was not freeing all transient state of the PGconn object. --- src/interfaces/libpq/fe-connect.c | 32 +++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 1ededb23e2..4da59226b7 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.313 2005/06/27 02:04:26 neilc Exp $ + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.314 2005/07/13 15:25:55 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1874,6 +1874,8 @@ makeEmptyPGconn(void) /* * freePGconn * - free the PGconn data structure + * + * When changing/adding to this function, see also closePGconn! */ static void freePGconn(PGconn *conn) @@ -1921,6 +1923,7 @@ freePGconn(PGconn *conn) free(conn->krbsrvname); #endif /* Note that conn->Pfdebug is not ours to close or free */ + freeaddrinfo_all(conn->addrlist_family, conn->addrlist); notify = conn->notifyHead; while (notify != NULL) { @@ -1929,7 +1932,6 @@ freePGconn(PGconn *conn) notify = notify->next; free(prev); } - freeaddrinfo_all(conn->addrlist_family, conn->addrlist); pstatus = conn->pstatus; while (pstatus != NULL) { @@ -1952,10 +1954,15 @@ freePGconn(PGconn *conn) /* * closePGconn * - properly close a connection to the backend + * + * Release all transient state, but NOT the connection parameters. */ static void closePGconn(PGconn *conn) { + PGnotify *notify; + pgParameterStatus *pstatus; + /* * Note that the protocol doesn't allow us to send Terminate messages * during the startup phase. @@ -1991,6 +1998,27 @@ closePGconn(PGconn *conn) * absent */ conn->asyncStatus = PGASYNC_IDLE; pqClearAsyncResult(conn); /* deallocate result and curTuple */ + freeaddrinfo_all(conn->addrlist_family, conn->addrlist); + conn->addrlist = NULL; + conn->addr_cur = NULL; + notify = conn->notifyHead; + while (notify != NULL) + { + PGnotify *prev = notify; + + notify = notify->next; + free(prev); + } + conn->notifyHead = NULL; + pstatus = conn->pstatus; + while (pstatus != NULL) + { + pgParameterStatus *prev = pstatus; + + pstatus = pstatus->next; + free(prev); + } + conn->pstatus = NULL; if (conn->lobjfuncs) free(conn->lobjfuncs); conn->lobjfuncs = NULL;