From ea618a9d2038ef1dd04c725e4943821095a8c501 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 unifies the 2 places num_active_persistent could be incremented: - the persistent branch, before jumping to end: - the main branch, where it was incremented f persistent was true and new_connection was true Now, we just increment in the end: block if persistent is true, and new_connection is no longer needed. Fixes GH-22631 --- ext/mysqli/mysqli_nonapi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 6f2aa50117a5..26926cbd7a2c 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -58,7 +58,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b zend_long port = 0, flags = 0; bool port_is_null = 1; zend_string *hash_key = NULL; - bool new_connection = false; zend_resource *le; mysqli_plist_entry *plist = NULL; bool self_alloced = 0; @@ -173,7 +172,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b if (!mysql_ping(mysql->mysql)) { #endif mysqlnd_restart_psession(mysql->mysql); - MyG(num_active_persistent)++; /* clear error */ php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql)); @@ -221,7 +219,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b if (!(mysql->mysql = mysqlnd_init(MYSQLND_CLIENT_NO_FLAG, persistent))) { goto err; } - new_connection = true; } if (ssl) { @@ -281,7 +278,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) { MyG(num_active_persistent)++; }