summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-12-10 11:21:06 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-12-10 11:23:41 +0100
commite450621f5e0a9490c287c8c71650f8b4d5ebbc2b (patch)
treeb227aa96151efedbb441842074d869e93751c702
parent4922049213f9630b9cfd8fe196ab770d74c5fc57 (diff)
downloadphp-git-e450621f5e0a9490c287c8c71650f8b4d5ebbc2b.tar.gz
Fixed bug #76815
When we receive an error while reading a result set, we should assume that no more result sets are available. libmysqlclient implements the same behavior.
-rw-r--r--NEWS2
-rw-r--r--ext/mysqlnd/mysqlnd_result.c7
-rw-r--r--ext/pdo_mysql/tests/bug76815.phpt33
3 files changed, 42 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 7eeea0c400..20f7da0f02 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,8 @@ PHP NEWS
queries"). (Nikita)
. Fixed bug #71145 (Multiple statements in init command triggers unbuffered
query error). (Nikita)
+ . Fixed bug #76815 (PDOStatement cannot be GCed/closeCursor-ed when a
+ PROCEDURE resultset SIGNAL). (Nikita)
- Phpdbg:
. Fixed bug #76813 (Access violation near NULL on source operand). (cmb)
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index 46d308d1f9..8a3ebb53a7 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -1359,6 +1359,13 @@ MYSQLND_METHOD(mysqlnd_res, store_result_fetch_data)(MYSQLND_CONN_DATA * const c
UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status, row_packet.server_status);
}
+ if (ret == FAIL) {
+ /* Error packets do not contain server status information. However, we know that after
+ * an error there will be no further result sets. */
+ UPSERT_STATUS_SET_SERVER_STATUS(conn->upsert_status,
+ UPSERT_STATUS_GET_SERVER_STATUS(conn->upsert_status) & ~SERVER_MORE_RESULTS_EXISTS);
+ }
+
/* save some memory */
if (free_rows) {
/* don't try to allocate more than possible - mnd_XXalloc expects size_t, and it can have narrower range than uint64_t */
diff --git a/ext/pdo_mysql/tests/bug76815.phpt b/ext/pdo_mysql/tests/bug76815.phpt
new file mode 100644
index 0000000000..b5c8577b07
--- /dev/null
+++ b/ext/pdo_mysql/tests/bug76815.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Bug #76815: PDOStatement cannot be GCed/closeCursor-ed when a PROCEDURE resultset SIGNAL
+--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');
+
+$pdo = MySQLPDOTest::factory();
+$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+
+$pdo->query('DROP FUNCTION IF EXISTS tst');
+$pdo->query('DROP PROCEDURE IF EXISTS tst2');
+$pdo->query('CREATE FUNCTION tst() RETURNS VARCHAR(5) DETERMINISTIC BEGIN RETURN \'x12345\'; END');
+$pdo->query('CREATE PROCEDURE tst2() BEGIN SELECT tst(); END');
+
+$st = $pdo->prepare('CALL tst2()');
+try {
+ $st->execute();
+} catch (PDOException $ex) {
+ echo $ex->getMessage(), "\n";
+}
+unset($st);
+echo "Ok.\n";
+
+?>
+--EXPECT--
+SQLSTATE[22001]: String data, right truncated: 1406 Data too long for column 'tst()' at row 1
+Ok.