Fix assorted resource leaks in new pg_createsubscriber code.

Various error paths did not release resources before returning.
While it's likely that the program would just exit shortly later,
none of the functions in question have summary exit(1) calls,
so they should not be assuming that.

Ranier Vilela and Tom Lane, per reports from Coverity

Discussion: https://postgr.es/m/CAEudQAr2_SZFxB4kXJiL4+2UaNZxUk5UBJtj0oXyJYMGZu-03g@mail.gmail.com
This commit is contained in:
Tom Lane 2024-04-01 13:47:27 -04:00
parent 6f47f68831
commit 91cbb4b492

View File

@ -251,8 +251,8 @@ usage(void)
static char * static char *
get_base_conninfo(const char *conninfo, char **dbname) get_base_conninfo(const char *conninfo, char **dbname)
{ {
PQExpBuffer buf = createPQExpBuffer(); PQExpBuffer buf;
PQconninfoOption *conn_opts = NULL; PQconninfoOption *conn_opts;
PQconninfoOption *conn_opt; PQconninfoOption *conn_opt;
char *errmsg = NULL; char *errmsg = NULL;
char *ret; char *ret;
@ -262,9 +262,11 @@ get_base_conninfo(const char *conninfo, char **dbname)
if (conn_opts == NULL) if (conn_opts == NULL)
{ {
pg_log_error("could not parse connection string: %s", errmsg); pg_log_error("could not parse connection string: %s", errmsg);
PQfreemem(errmsg);
return NULL; return NULL;
} }
buf = createPQExpBuffer();
i = 0; i = 0;
for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++) for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
{ {
@ -497,9 +499,10 @@ connect_database(const char *conninfo, bool exit_on_error)
{ {
pg_log_error("connection to database failed: %s", pg_log_error("connection to database failed: %s",
PQerrorMessage(conn)); PQerrorMessage(conn));
PQfinish(conn);
if (exit_on_error) if (exit_on_error)
exit(1); exit(1);
return NULL; return NULL;
} }
@ -509,9 +512,11 @@ connect_database(const char *conninfo, bool exit_on_error)
{ {
pg_log_error("could not clear search_path: %s", pg_log_error("could not clear search_path: %s",
PQresultErrorMessage(res)); PQresultErrorMessage(res));
PQclear(res);
PQfinish(conn);
if (exit_on_error) if (exit_on_error)
exit(1); exit(1);
return NULL; return NULL;
} }
PQclear(res); PQclear(res);
@ -941,6 +946,8 @@ check_publisher(const struct LogicalRepInfo *dbinfo)
failed = true; failed = true;
} }
pg_free(wal_level);
if (failed) if (failed)
exit(1); exit(1);
} }
@ -1209,6 +1216,8 @@ create_logical_replication_slot(PGconn *conn, struct LogicalRepInfo *dbinfo)
pg_log_error("could not create replication slot \"%s\" on database \"%s\": %s", pg_log_error("could not create replication slot \"%s\" on database \"%s\": %s",
slot_name, dbinfo->dbname, slot_name, dbinfo->dbname,
PQresultErrorMessage(res)); PQresultErrorMessage(res));
PQclear(res);
destroyPQExpBuffer(str);
return NULL; return NULL;
} }