Skip to content

Commit

Permalink
Fixed bug #76815
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Dec 10, 2020
1 parent 4922049 commit e450621
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions ext/mysqlnd/mysqlnd_result.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
33 changes: 33 additions & 0 deletions ext/pdo_mysql/tests/bug76815.phpt
Original file line number Diff line number Diff line change
@@ -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.

0 comments on commit e450621

Please sign in to comment.