From fcabe693ba19ff60fc735aebe42f8ccc5f139bec Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 8 Oct 2021 14:58:18 +0200 Subject: [PATCH] Fixed bug #81494 Use the proper error reporting mechanism rather than throwing a warning. This requires something of a hack because we don't have direct access to the connection object at this point. --- NEWS | 3 +++ ext/mysqli/mysqli.c | 11 +++++++++++ ext/mysqli/tests/bug64726.phpt | 3 ++- ext/mysqli/tests/bug79375.phpt | 4 +--- ext/mysqlnd/mysqlnd_result.c | 1 - 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index acff9267fa5..2e101e757fa 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.4.26 +- MySQLi: + . Fixed bug #81494 (Stopped unbuffered query does not throw error). (Nikita) + - Streams: . Fixed bug #54340 (Memory corruption with user_filter). (Nikita) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index c4dbcb251a6..fef629eb084 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1202,6 +1202,17 @@ void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend } #else mysqlnd_fetch_into(result, ((fetchtype & MYSQLI_NUM)? MYSQLND_FETCH_NUM:0) | ((fetchtype & MYSQLI_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQLI); + /* TODO: We don't have access to the connection object at this point, so we use low-level + * mysqlnd APIs to access the error information. We should try to pass through the connection + * object instead. */ + if (MyG(report_mode) & MYSQLI_REPORT_ERROR) { + MYSQLND_CONN_DATA *conn = result->conn; + unsigned error_no = conn->m->get_error_no(conn); + if (error_no) { + php_mysqli_report_error( + conn->m->get_sqlstate(conn), error_no, conn->m->get_error_str(conn)); + } + } #endif } /* }}} */ diff --git a/ext/mysqli/tests/bug64726.phpt b/ext/mysqli/tests/bug64726.phpt index 8f24ad09b70..9336012f0bb 100644 --- a/ext/mysqli/tests/bug64726.phpt +++ b/ext/mysqli/tests/bug64726.phpt @@ -14,10 +14,11 @@ require_once('skipifconnectfailure.inc'); require 'connect.inc'; $db = new my_mysqli($host, $user, $passwd, $db, $port, $socket); +mysqli_report(MYSQLI_REPORT_ERROR); $result = $db->query('SELECT 1', MYSQLI_USE_RESULT); $db->close(); var_dump($result->fetch_object()); ?> --EXPECTF-- -Warning: mysqli_result::fetch_object(): Error while reading a row in %sbug64726.php on line %d +Warning: mysqli_result::fetch_object(): (HY000/2014): Commands out of sync; you can't run this command now in %s on line %d bool(false) diff --git a/ext/mysqli/tests/bug79375.phpt b/ext/mysqli/tests/bug79375.phpt index 6c6176311da..49c4812061b 100644 --- a/ext/mysqli/tests/bug79375.phpt +++ b/ext/mysqli/tests/bug79375.phpt @@ -167,6 +167,4 @@ Lock wait timeout exceeded; try restarting transaction Running query on first connection Got 1 for first connection Running query on second connection - -Warning: mysqli_result::fetch_row(): Error while reading a row in %s on line %d -Got 0 for second connection +Lock wait timeout exceeded; try restarting transaction diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 8a3ebb53a77..4dcaf121fb7 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -1753,7 +1753,6 @@ MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int } array_init_size(return_value, array_size); if (FAIL == result->m.fetch_row(result, (void *)return_value, flags, &fetched_anything)) { - php_error_docref(NULL, E_WARNING, "Error while reading a row"); zend_array_destroy(Z_ARR_P(return_value)); RETVAL_FALSE; } else if (fetched_anything == FALSE) {