]> granicus.if.org Git - php/commitdiff
Fixed bug #67004
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 11 Dec 2020 11:43:19 +0000 (12:43 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 11 Dec 2020 11:52:59 +0000 (12:52 +0100)
Repeated execute() with native PS failed to release the previous
result set on libmysqlclient.

Move freeing the result set into a common location.

NEWS
ext/pdo_mysql/mysql_statement.c
ext/pdo_mysql/tests/bug67004.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ebd59377ddec220d7135fb7984eb3291a104846d..b43b0a09a697c46a37c1f2616751cee8a9cfb9ef 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,8 @@ PHP                                                                        NEWS
   . Fixed bug #72368 (PdoStatement->execute() fails but does not throw an
     exception). (Nikita)
   . Fixed bug #62889 (LOAD DATA INFILE broken). (Nikita)
+  . Fixed bug #67004 (Executing PDOStatement::fetch() more than once prevents
+    releasing resultset). (Nikita)
 
 - Phar:
   . Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
index 80d8747cd96ee57b2f2be948eb753b4aada75090..9a9249d42f0d4c890e3b17d16928d48dc9fca6ed 100644 (file)
@@ -303,7 +303,6 @@ static int pdo_mysql_stmt_execute_prepared_mysqlnd(pdo_stmt_t *stmt) /* {{{ */
                PDO_DBG_RETURN(0);
        }
 
-       pdo_mysql_free_result(S);
        PDO_DBG_RETURN(pdo_mysql_stmt_after_execute_prepared(stmt));
 }
 /* }}} */
@@ -316,14 +315,14 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
        PDO_DBG_ENTER("pdo_mysql_stmt_execute");
        PDO_DBG_INF_FMT("stmt=%p", S->stmt);
 
+       /* ensure that we free any previous unfetched results */
+       pdo_mysql_free_result(S);
        S->done = 0;
+
        if (S->stmt) {
                PDO_DBG_RETURN(pdo_mysql_stmt_execute_prepared(stmt));
        }
 
-       /* ensure that we free any previous unfetched results */
-       pdo_mysql_free_result(S);
-
        if (mysql_real_query(H->server, stmt->active_query_string, stmt->active_query_stringlen) != 0) {
                pdo_mysql_error_stmt(stmt);
                PDO_DBG_RETURN(0);
diff --git a/ext/pdo_mysql/tests/bug67004.phpt b/ext/pdo_mysql/tests/bug67004.phpt
new file mode 100644 (file)
index 0000000..98b0a08
--- /dev/null
@@ -0,0 +1,34 @@
+--TEST--
+Bug #67004: Executing PDOStatement::fetch() more than once prevents releasing resultset
+--SKIPIF--
+<?php
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'skipif.inc');
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+MySQLPDOTest::skip();
+?>
+--FILE--
+<?php
+
+require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+$dbh = MySQLPDOTest::factory();
+$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
+$dbh->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+$stmt = $dbh->prepare("SELECT ?");
+
+$stmt->execute(["foo"]);
+var_dump($stmt->fetchColumn(0));
+
+$stmt->execute(["bar"]);
+var_dump($stmt->fetchColumn(0));
+
+$stmt = $dbh->prepare("SELECT ?");
+$stmt->execute(["baz"]);
+var_dump($stmt->fetchColumn(0));
+
+?>
+--EXPECT--
+string(3) "foo"
+string(3) "bar"
+string(3) "baz"