Bug #66370 [NEW]: Errors in mysqli_store_result() don't not set mysqli error/errno

From: Date: Tue, 31 Dec 2013 03:23:52 +0000
Subject: Bug #66370 [NEW]: Errors in mysqli_store_result() don't not set mysqli error/errno
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-183502@lists.php.net to get a copy of this message
From:             bugs dot php dot net at ss dot chernousov dot net
Operating system: Gentoo Linux
PHP version:      5.5.7
Package:          MySQLi related
Bug Type:         Bug
Bug description:Errors in mysqli_store_result() don't not set mysqli error/errno

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=

-- 
Edit bug report at https://bugs.php.net/bug.php?id=66370&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=66370&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=66370&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=66370&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=66370&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=66370&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=66370&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=66370&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=66370&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=66370&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=66370&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=66370&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=66370&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=66370&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=66370&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=66370&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=66370&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=66370&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=66370&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=66370&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=66370&r=mysqlcfg



Thread (7 messages)

« previous php.bugs (#183502) next »