Fix use-after-free error reported by Neil Conway.
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 30 Jun 2006 15:06:05 +0000 (15:06 +0000)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 30 Jun 2006 15:06:05 +0000 (15:06 +0000)
src/bin/psql/common.c

index c35d3c3eef5d8ab7bca3dd875143492df82f9abf..fe7d508a438541ad2ed1b4d94c49eaeafa1bf1d6 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2006, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.119 2006/06/14 16:49:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.120 2006/06/30 15:06:05 alvherre Exp $
  */
 #include "postgres_fe.h"
 #include "common.h"
@@ -875,19 +875,19 @@ SendQuery(const char *query)
        if (OK)
                OK = PrintQueryResults(results);
 
-       PQclear(results);
-
        /* If we made a temporary savepoint, possibly release/rollback */
        if (on_error_rollback_savepoint)
        {
+               PGresult   *svptres;
+
                transaction_status = PQtransactionStatus(pset.db);
 
                /* We always rollback on an error */
                if (transaction_status == PQTRANS_INERROR)
-                       results = PQexec(pset.db, "ROLLBACK TO pg_psql_temporary_savepoint");
+                       svptres = PQexec(pset.db, "ROLLBACK TO pg_psql_temporary_savepoint");
                /* If they are no longer in a transaction, then do nothing */
                else if (transaction_status != PQTRANS_INTRANS)
-                       results = NULL;
+                       svptres = NULL;
                else
                {
                        /*
@@ -898,20 +898,22 @@ SendQuery(const char *query)
                        if (strcmp(PQcmdStatus(results), "SAVEPOINT") == 0 ||
                                strcmp(PQcmdStatus(results), "RELEASE") == 0 ||
                                strcmp(PQcmdStatus(results), "ROLLBACK") == 0)
-                               results = NULL;
+                               svptres = NULL;
                        else
-                               results = PQexec(pset.db, "RELEASE pg_psql_temporary_savepoint");
+                               svptres = PQexec(pset.db, "RELEASE pg_psql_temporary_savepoint");
                }
-               if (PQresultStatus(results) != PGRES_COMMAND_OK)
+               if (svptres && PQresultStatus(svptres) != PGRES_COMMAND_OK)
                {
                        psql_error("%s", PQerrorMessage(pset.db));
                        PQclear(results);
+                       PQclear(svptres);
                        ResetCancelConn();
                        return false;
                }
-               PQclear(results);
        }
 
+       PQclear(results);
+
        /* Possible microtiming output */
        if (OK && pset.timing)
                printf(_("Time: %.3f ms\n"), DIFF_MSEC(&after, &before));