php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #66370 Errors in mysqli_store_result() do not set mysqli error/errno
Submitted: 2013-12-31 03:23 UTC Modified: 2020-10-29 10:01 UTC
Votes:10
Avg. Score:4.4 ± 0.7
Reproduced:8 of 8 (100.0%)
Same Version:1 (12.5%)
Same OS:3 (37.5%)
From: bugs dot php dot net at ss dot chernousov dot net Assigned: nikic (profile)
Status: Closed Package: MySQLi related
PHP Version: 5.5.7 OS: Gentoo Linux
Private report: No CVE-ID: None
 [2013-12-31 03:23 UTC] bugs dot php dot net at ss dot chernousov dot net
Description:
------------
(This is related to mysqlnd in general, not only to mysqli).

When connection gets broken while store_result()/query() is transferring data, "Empty row packet body" warning is generated, but errno/error are not set. Any following mysql-network-related function generates 2006/"MySQL server has gone away" and correctly sets errno/error. Expected behaviour: store_result()/query() to set errno/error immediately after an error happened.


More digging details below.

store_result() generates one Warning ("Empty row packet body"), but query() generates two:

Warning: Empty row packet body in 1.php on line 5
Warning: mysqli::query(): (00000/0):  in 1.php on line 5

And neither of them sets errno/error.

I added CONN_SET_STATE(conn, CONN_QUIT_SENT) and SET_CLIENT_ERROR(*conn->error_info, ...) to php_mysqlnd_read_row_ex() in mysqlnd_wireprotocol.c (similarly to PACKET_READ_HEADER_AND_BODY macro), and found another problem: errors from mysqlnd_wireprotocol.c are set to *conn->error_info, but store_result_fetch_data() in mysqlnd_result.c expects errors in row_packet->error_info. It seems that errors generated in mysqlnd_wireprotocol.c are never actually used in mysqlnd_result.c. Furthermore, connection state set in mysqlnd_wireprotocol.c is always overwritten in mysqlnd_result.c with either CONN_NEXT_RESULT_PENDING or CONN_READY.

I ended up with the following patch to at least set correct errno/error on store_result()/query(), so the script can get aware about lost connections timely. However this patch is definitely not a complete solution, it doesn't fix neither double warning nor connection state (and it looks like it's not the only place where warnings are raised but errno/error are not set).

Test script:
---------------
<?php

// connect to a remote server, slow connection is preferrable (so you'll have more time to kill the connection)
// while script is performing $mysqli->query(), kill the connection using mysql "kill" command (killall -9 mysqld would work too :))

$mysqli = new mysqli('remote-host', 'user', 'password');
$mysqli->query('set global max_allowed_packet=' . 60e6); // 60M
// echo "Do this in mysql shell: kill {$mysqli->threadid}\n";
$mysqli->query('select repeat("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", 500000)'); // ~50M packet
echo "errno={$mysqli->errno}, error={$mysqli->error}\n";

Expected result:
----------------
Warning: mysqli::query(): (HY000/2006): MySQL server has gone away in 1.php on line 9
errno=2006, error=MySQL server has gone away

Actual result:
--------------
Warning: Empty row packet body in 1.php on line 9
Warning: mysqli::query(): (00000/0):  in 1.php on line 9
errno=0, error=

Patches

mysqlnd-errno-error-fix.patch (last revision 2013-12-31 03:24 UTC by bugs dot php dot net at ss dot chernousov dot net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-02-17 11:47 UTC] andrey@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: andrey
 [2016-08-04 11:31 UTC] sergey at dotsgo dot com
Just stuck with the same issue while dealing with a mysql server on another continent and transferring large amounts of data on an unreliable connection.
 [2017-10-24 07:21 UTC] kalle@php.net
-Status: Assigned +Status: Open -Assigned To: andrey +Assigned To:
 [2017-10-24 14:59 UTC] bugs dot php dot net at ss dot chernousov dot net
-Summary: Errors in mysqli_store_result() don't not set mysqli error/errno +Summary: Errors in mysqli_store_result() do not set mysqli error/errno
 [2017-10-24 14:59 UTC] bugs dot php dot net at ss dot chernousov dot net
(fixed summary title)
 [2020-10-29 10:01 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 19 14:01:28 2024 UTC