]> granicus.if.org Git - postgresql/commitdiff
Fix memory leaks in libpqwalreceiver
authorPeter Eisentraut <peter_e@gmx.net>
Mon, 23 Jan 2017 16:06:30 +0000 (11:06 -0500)
committerPeter Eisentraut <peter_e@gmx.net>
Mon, 23 Jan 2017 16:06:30 +0000 (11:06 -0500)
The results of the libpq functions PQescapeIdentifier() and
PQescapeLiteral() must be freed explicitly.  Also handle errors in these
functions better.

src/backend/replication/libpqwalreceiver/libpqwalreceiver.c

index 7df3698afb24036bcc6d224f8871686e25583687..44a89c73fde9876fe38e650fbc74d92f90db8d94 100644 (file)
@@ -304,17 +304,30 @@ libpqrcv_startstreaming(WalReceiverConn *conn,
        {
                char   *pubnames_str;
                List   *pubnames;
+               char   *pubnames_literal;
 
                appendStringInfoString(&cmd, " (");
+
                appendStringInfo(&cmd, "proto_version '%u'",
                                                 options->proto.logical.proto_version);
+
                pubnames = options->proto.logical.publication_names;
                pubnames_str = stringlist_to_identifierstr(conn->streamConn, pubnames);
-               appendStringInfo(&cmd, ", publication_names %s",
-                                                PQescapeLiteral(conn->streamConn, pubnames_str,
-                                                                                strlen(pubnames_str)));
-               appendStringInfoChar(&cmd, ')');
+               if (!pubnames_str)
+                       ereport(ERROR,
+                                       (errmsg("could not start WAL streaming: %s",
+                                                       PQerrorMessage(conn->streamConn))));
+               pubnames_literal = PQescapeLiteral(conn->streamConn, pubnames_str,
+                                                                                  strlen(pubnames_str));
+               if (!pubnames_literal)
+                       ereport(ERROR,
+                                       (errmsg("could not start WAL streaming: %s",
+                                                       PQerrorMessage(conn->streamConn))));
+               appendStringInfo(&cmd, ", publication_names %s", pubnames_literal);
+               PQfreemem(pubnames_literal);
                pfree(pubnames_str);
+
+               appendStringInfoChar(&cmd, ')');
        }
        else
                appendStringInfo(&cmd, " TIMELINE %u",
@@ -736,14 +749,21 @@ stringlist_to_identifierstr(PGconn *conn, List *strings)
        foreach (lc, strings)
        {
                char *val = strVal(lfirst(lc));
+               char *val_escaped;
 
                if (first)
                        first = false;
                else
                        appendStringInfoChar(&res, ',');
 
-               appendStringInfoString(&res,
-                                                          PQescapeIdentifier(conn, val, strlen(val)));
+               val_escaped = PQescapeIdentifier(conn, val, strlen(val));
+               if (!val_escaped)
+               {
+                       free(res.data);
+                       return NULL;
+               }
+               appendStringInfoString(&res, val_escaped);
+               PQfreemem(val_escaped);
        }
 
        return res.data;