From 8db991c1119aba863162dd221f569d3a0ec5629d Mon Sep 17 00:00:00 2001 From: Mark Date: Wed, 15 Jul 2026 18:36:16 +0000 Subject: [PATCH] ext/mysqli: fix corruption of num_active_persistent when using real_connect() Fix GH-22631: ext/mysqli: mysqli double increments num_active_persistent... In mysqli_common_connect(), when is_real_connect is set and a persistent connection is requested, both the persistent connection branch and the normal function flow (in the end: label) increment the num_active_persistent counter. num_active_persistent is also decremented once as a result of cleaning up old persistent connection state, but this still results in the counter growing by 1 every time we reuse an existing connection, and becoming invalid. This can cause later non-cached persistent connection attempts to fail the max_persistent limit check, depsite there not actually being that many persistent connections. This commit adds a flag from_pool which is set when a connection is found in the persistent connection pool, and which prevents the counter increment in the end: label from firing. Fixes GH-22631 --- ext/mysqli/mysqli_nonapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 6f2aa50117a5..fd3f3a5a4b36 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -59,6 +59,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b bool port_is_null = 1; zend_string *hash_key = NULL; bool new_connection = false; + bool from_pool = false; zend_resource *le; mysqli_plist_entry *plist = NULL; bool self_alloced = 0; @@ -174,6 +175,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b #endif mysqlnd_restart_psession(mysql->mysql); MyG(num_active_persistent)++; + from_pool = true; /* clear error */ php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql)); @@ -281,7 +283,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b mysqli_resource->status = MYSQLI_STATUS_VALID; /* store persistent connection */ - if (persistent && (new_connection || is_real_connect)) { + if (persistent && (new_connection || is_real_connect) && !from_pool) { MyG(num_active_persistent)++; }