Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 555b603

Browse files
authored
mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT (#13618)
1 parent f61aad8 commit 555b603

File tree

6 files changed

+59
-2
lines changed

6 files changed

+59
-2
lines changed

‎NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ PHP NEWS
3434
. Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb,
3535
Kamil Tekiela)
3636

37+
- PDO_MYSQL:
38+
. mysqlnd: support ER_CLIENT_INTERACTION_TIMEOUT. (Appla)
39+
3740
- Session:
3841
. Emit warnings for non-positive values of session.gc_divisor and negative values
3942
of session.gc_probability. (Jorg Sowa)

‎UPGRADING‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ PHP 8.4 UPGRADE NOTES
126126
has changed. Consult https://github.com/PCRE2Project/pcre2/blob/master/NEWS
127127
for a full changelog.
128128

129+
- MySQLnd
130+
. The error code reported for MySQL server wait timeouts has been changed from 2006
131+
to 4031 for MySQL server versions 8.0.24 and above.
132+
129133
- PCNTL:
130134
. The functions pcntl_sigprocmask(), pcntl_sigwaitinfo() and
131135
pcntl_sigtimedwait() now throw:

‎ext/mysqli/tests/bug81335.phpt‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Bug #81335: Packets out of order after connection timeout
3+
--EXTENSIONS--
4+
mysqli
5+
--SKIPIF--
6+
<?php
7+
if (PHP_OS === 'WINNT') die('skip on windows');
8+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
9+
10+
require_once 'connect.inc';
11+
if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die("skip cannot connect");
12+
if (mysqli_get_server_version($link) < 80024 || str_contains(mysqli_get_server_info($link), 'MariaDB')) {
13+
die("skip: Due to many MySQL Server differences, the test requires >= 8.0.24");
14+
}
15+
?>
16+
--FILE--
17+
<?php
18+
19+
require_once 'connect.inc';
20+
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
21+
$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket);
22+
$mysqli->query('SET WAIT_TIMEOUT=1');
23+
usleep(1000000 * 1.1);
24+
try {
25+
$mysqli->query('SELECT 1 + 1');
26+
} catch(mysqli_sql_exception $e) {
27+
echo $e->getMessage();
28+
echo "\n";
29+
echo $e->getCode();
30+
}
31+
?>
32+
--EXPECTF--
33+
The client was disconnected by the server because of inactivity. See wait_timeout and interactive_timeout for configuring this behavior.
34+
4031

‎ext/mysqlnd/mysqlnd_enum_n_def.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@
130130
#define CR_INVALID_PARAMETER_NO 2034
131131
#define CR_INVALID_BUFFER_USE 2035
132132
#define CR_LOAD_DATA_LOCAL_INFILE_REJECTED 2068
133+
#define CR_CLIENT_INTERACTION_TIMEOUT 4031
133134

134135
#define MYSQLND_EE_FILENOTFOUND 7890
135136

‎ext/mysqlnd/mysqlnd_result.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * s)
183183
UPSERT_STATUS_SET_AFFECTED_ROWS_TO_ERROR(conn->upsert_status);
184184

185185
if (FAIL == (ret = PACKET_READ(conn, &rset_header))) {
186-
if (conn->error_info->error_no != CR_SERVER_GONE_ERROR) {
186+
if (conn->error_info->error_no != CR_SERVER_GONE_ERROR&&conn->error_info->error_no!=CR_CLIENT_INTERACTION_TIMEOUT) {
187187
php_error_docref(NULL, E_WARNING, "Error reading result set's header");
188188
}
189189
break;

‎ext/mysqlnd/mysqlnd_wireprotocol.c‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,19 @@ mysqlnd_read_header(MYSQLND_PFC * pfc, MYSQLND_VIO * vio, MYSQLND_PACKET_HEADER
267267
pfc->data->packet_no++;
268268
DBG_RETURN(PASS);
269269
}
270+
// @see https://dev.mysql.com/worklog/task/?id=12999
271+
if (header->size > 0) {
272+
zend_uchar *buf = mnd_emalloc(header->size);
273+
if ((PASS == pfc->data->m.receive(pfc, vio, buf, header->size, conn_stats, error_info)) && buf[0] == ERROR_MARKER) {
274+
php_mysqlnd_read_error_from_line(buf + 1, header->size - 1,
275+
error_info->error, sizeof(error_info->error),
276+
&error_info->error_no, error_info->sqlstate
277+
);
278+
mnd_efree(buf);
279+
DBG_RETURN(FAIL);
280+
}
281+
mnd_efree(buf);
282+
}
270283

271284
DBG_ERR_FMT("Logical link: packets out of order. Expected %u received %u. Packet size=%zu",
272285
pfc->data->packet_no, header->packet_no, header->size);
@@ -294,7 +307,9 @@ mysqlnd_read_packet_header_and_body(MYSQLND_PACKET_HEADER * packet_header,
294307
DBG_INF_FMT("buf=%p size=%zu", buf, buf_size);
295308
if (FAIL == mysqlnd_read_header(pfc, vio, packet_header, stats, error_info)) {
296309
SET_CONNECTION_STATE(connection_state, CONN_QUIT_SENT);
297-
SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
310+
if (error_info->error_no == 0) {
311+
SET_CLIENT_ERROR(error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
312+
}
298313
DBG_ERR_FMT("Can't read %s's header", packet_type_as_text);
299314
DBG_RETURN(FAIL);
300315
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /