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

index 80d4c91c009a158fd8a937b75f8c7f9e856f35e9..0699bc00704484382a197b300889c5e3c8aa00fb 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2005, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.110.2.1 2005/11/22 18:23:27 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/common.c,v 1.110.2.2 2006/06/30 15:06:16 alvherre Exp $
  */
 #include "postgres_fe.h"
 #include "common.h"
@@ -1067,19 +1067,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
                {
                        /*
@@ -1090,20 +1090,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));