From 67ef59b42030eab47720e5af2a771c2d1786338a Mon Sep 17 00:00:00 2001 From: Appla Date: Fri, 8 Mar 2024 10:34:58 +0800 Subject: [PATCH] ext/mysqlnd: fixed known issues and added test case --- ext/mysqli/tests/bug81335.phpt | 38 ++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_enum_n_def.h | 2 +- ext/mysqlnd/mysqlnd_result.c | 2 +- ext/mysqlnd/mysqlnd_wireprotocol.c | 13 ++++------ 4 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 ext/mysqli/tests/bug81335.phpt diff --git a/ext/mysqli/tests/bug81335.phpt b/ext/mysqli/tests/bug81335.phpt new file mode 100644 index 0000000000000..bf5ef40bf1b41 --- /dev/null +++ b/ext/mysqli/tests/bug81335.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #81335: Packets out of order after connection timeout +--EXTENSIONS-- +mysqli +--SKIPIF-- +close(); + die("skip: Due to many MySQL Server differences, the test requires >= 8.0.24"); +} +$link->close(); +?> +--FILE-- +query('SET WAIT_TIMEOUT=1'); +usleep(1000000 * 1.1); +try { + $mysqli->query('SELECT SLEEP(1)'); +} catch(mysqli_sql_exception $e) { + echo $e->getMessage(); + echo "\n"; + echo $e->getCode(); +} +$mysqli->close(); +?> +--EXPECTF-- +The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior. +4031 diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 3022d16207f58..56b28a28f53da 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -130,7 +130,7 @@ #define CR_INVALID_PARAMETER_NO 2034 #define CR_INVALID_BUFFER_USE 2035 #define CR_LOAD_DATA_LOCAL_INFILE_REJECTED 2068 -#define ER_CLIENT_INTERACTION_TIMEOUT 4031 +#define CR_CLIENT_INTERACTION_TIMEOUT 4031 #define MYSQLND_EE_FILENOTFOUND 7890 diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 783863785a29c..cab0889cec9ea 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -183,7 +183,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s) UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status); if (FAIL == (ret = PACKET_READ(conn, &rset_header))) { - if (conn->error_info->error_no != CR_SERVER_GONE_ERROR && conn->error_info->error_no != ER_CLIENT_INTERACTION_TIMEOUT) { + if (conn->error_info->error_no != CR_SERVER_GONE_ERROR && conn->error_info->error_no != CR_CLIENT_INTERACTION_TIMEOUT) { php_error_docref(NULL, E_WARNING, "Error reading result set's header"); } break; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 68b9aa625f744..4d762363514ba 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -269,21 +269,16 @@ mysqlnd_read_header(MYSQLND_PFC * pfc, MYSQLND_VIO * vio, MYSQLND_PACKET_HEADER } // @see https://dev.mysql.com/worklog/task/?id=12999 if (header->size > 0) { - DBG_ERR_FMT("Logical link: try reap pending data. Packet size=%zu", header->size); - zend_uchar *buf = emalloc(header->size); + zend_uchar *buf = mnd_emalloc(header->size); if ((PASS == pfc->data->m.receive(pfc, vio, buf, header->size, conn_stats, error_info)) && buf[0] == ERROR_MARKER) { php_mysqlnd_read_error_from_line(buf + 1, header->size - 1, error_info->error, sizeof(error_info->error), &error_info->error_no, error_info->sqlstate ); - if (error_info->error_no == ER_CLIENT_INTERACTION_TIMEOUT) { - efree(buf); - DBG_RETURN(FAIL); - } else { - error_info->error_no = 0; - } + mnd_efree(buf); + DBG_RETURN(FAIL); } - efree(buf); + mnd_efree(buf); } DBG_ERR_FMT("Logical link: packets out of order. Expected %u received %u. Packet size=%zu",