Skip to content

Commit a66d73d

Browse files
committed
Fixed bug #65825
Set error_info when we fail to read a packet, instead of throwing a warning. Additionally we also need to populate the right error_info in rowp_read -- we'll later take the error from the packet, not the connection. No test case, as this is hard to reliably test. I'm using the test case from: #2131 (comment)
1 parent f547412 commit a66d73d

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ PHP NEWS
4444
- PDO MySQL:
4545
. Fixed bug #66528 (No PDOException or errorCode if database becomes
4646
unavailable before PDO::commit). (Nikita)
47+
. Fixed bug #65825 (PDOStatement::fetch() does not throw exception on broken
48+
server connection). (Nikita)
4749

4850
29 Oct 2020, PHP 7.4.12
4951

ext/mysqlnd/mysqlnd_wireprotocol.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,15 @@ php_mysqlnd_rset_field_read(MYSQLND_CONN_DATA * conn, void * _packet)
13541354
}
13551355
/* }}} */
13561356

1357+
/* Like SET_CLIENT_ERROR, but for packet error_info. The type is the same,
1358+
* but only some parts of it are used. */
1359+
static void set_packet_error(
1360+
MYSQLND_ERROR_INFO *info, unsigned err_no, const char *sqlstate, const char *error)
1361+
{
1362+
info->error_no = err_no;
1363+
strlcpy(info->sqlstate, sqlstate, sizeof(info->sqlstate));
1364+
strlcpy(info->error, error, sizeof(info->error));
1365+
}
13571366

13581367
/* {{{ php_mysqlnd_read_row_ex */
13591368
static enum_func_status
@@ -1396,7 +1405,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
13961405

13971406
if (UNEXPECTED(PASS != (ret = pfc->data->m.receive(pfc, vio, p, header.size, stats, error_info)))) {
13981407
DBG_ERR("Empty row packet body");
1399-
php_error(E_WARNING, "Empty row packet body");
1408+
set_packet_error(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
14001409
} else {
14011410
while (header.size >= MYSQLND_MAX_PACKET_SIZE) {
14021411
if (FAIL == mysqlnd_read_header(pfc, vio, &header, stats, error_info)) {
@@ -1425,7 +1434,7 @@ php_mysqlnd_read_row_ex(MYSQLND_PFC * pfc,
14251434

14261435
if (PASS != (ret = pfc->data->m.receive(pfc, vio, p, header.size, stats, error_info))) {
14271436
DBG_ERR("Empty row packet body");
1428-
php_error(E_WARNING, "Empty row packet body");
1437+
set_packet_error(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
14291438
break;
14301439
}
14311440
}
@@ -1720,8 +1729,8 @@ php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_ROW_BUFFER * row_buffer, zval * fi
17201729
static enum_func_status
17211730
php_mysqlnd_rowp_read(MYSQLND_CONN_DATA * conn, void * _packet)
17221731
{
1723-
MYSQLND_PACKET_ROW *packet= (MYSQLND_PACKET_ROW *) _packet;
1724-
MYSQLND_ERROR_INFO * error_info = conn->error_info;
1732+
MYSQLND_PACKET_ROW *packet = (MYSQLND_PACKET_ROW *) _packet;
1733+
MYSQLND_ERROR_INFO * error_info = &packet->error_info;
17251734
MYSQLND_PFC * pfc = conn->protocol_frame_codec;
17261735
MYSQLND_VIO * vio = conn->vio;
17271736
MYSQLND_STATS * stats = conn->stats;

0 commit comments

Comments
 (0)