Skip to content

Commit 3014659

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
2 parents 8a67fc2 + 9a3f378 commit 3014659

4 files changed

Lines changed: 37 additions & 10 deletions

File tree

‎NEWS‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ PHP NEWS
7272

7373
- MySQLnd:
7474
. Fixed field_count not resetting on OK packet. (Kamil Tekiela)
75+
. Fixed memory leak when closing a prepared statement after its connection
76+
was killed. (Kamil Tekiela)
7577

7678
- Opcache:
7779
. Fixed OSS-Fuzz #546798343 (Heap-buffer-overflow in optimizer with

‎ext/mysqli/mysqli.c‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ void php_clear_stmt_bind(MY_STMT *stmt)
115115
if (stmt->stmt) {
116116
if (mysqli_stmt_close(stmt->stmt, true)) {
117117
php_error_docref(NULL, E_WARNING, "Error occurred while closing statement");
118-
return;
119118
}
120119
}
121120

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Closing a prepared statement after its connection was killed must not leak
3+
--EXTENSIONS--
4+
mysqli
5+
--SKIPIF--
6+
<?php
7+
require_once 'skipifconnectfailure.inc';
8+
?>
9+
--FILE--
10+
<?php
11+
require_once 'connect.inc';
12+
13+
mysqli_report(MYSQLI_REPORT_OFF);
14+
$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
15+
16+
$stmts = [];
17+
for ($i = 0; $i < 20; $i++) {
18+
$stmts[] = $link->prepare('DO 1');
19+
}
20+
$link->query('KILL ' . $link->thread_id);
21+
22+
// Over TCP, a few COM_STMT_CLOSE writes may be accepted before one fails
23+
do {
24+
array_pop($stmts);
25+
usleep(1000);
26+
} while ($stmts && !$link->errno);
27+
28+
echo "done!\n";
29+
?>
30+
--EXPECTF--
31+
Warning: main(): Error occurred while closing statement in %s on line %d
32+
done!

‎ext/mysqlnd/mysqlnd_ps.c‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, close_on_server)(MYSQLND_STMT * const s, bo
17581758
MYSQLND_STMT_DATA * stmt = s? s->data : NULL;
17591759
MYSQLND_CONN_DATA * conn = stmt? stmt->conn : NULL;
17601760
enum_mysqlnd_collected_stats statistic = STAT_LAST;
1761+
enum_func_status ret = PASS;
17611762

17621763
DBG_ENTER("mysqlnd_stmt::close_on_server");
17631764
if (!stmt || !conn) {
@@ -1795,14 +1796,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, close_on_server)(MYSQLND_STMT * const s, bo
17951796
STAT_FREE_RESULT_EXPLICIT);
17961797

17971798
if (GET_CONNECTION_STATE(&conn->state) == CONN_READY) {
1798-
enum_func_status ret = FAIL;
1799-
const size_t stmt_id = stmt->stmt_id;
1800-
1801-
ret = conn->command->stmt_close(conn, stmt_id);
1802-
if (ret == FAIL) {
1803-
COPY_CLIENT_ERROR(stmt->error_info, *conn->error_info);
1804-
DBG_RETURN(FAIL);
1805-
}
1799+
ret = conn->command->stmt_close(conn, stmt->stmt_id);
18061800
}
18071801
}
18081802
switch (stmt->execute_count) {
@@ -1831,7 +1825,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_stmt, close_on_server)(MYSQLND_STMT * const s, bo
18311825
stmt->conn = NULL;
18321826
}
18331827

1834-
DBG_RETURN(PASS);
1828+
DBG_RETURN(ret);
18351829
}
18361830
/* }}} */
18371831

0 commit comments

Comments
 (0)