Skip to content

Commit c8fb571

Browse files
committed
Fix crash in shutdown when using a named pipe with a persistent mysqli connection
The code originally posted in GH-10599 triggers the bug for non-persistent connections, but changing the host to `p:.` reveals that there is also a crash bug for persistent connections.
1 parent c04565a commit c8fb571

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

ext/mysqlnd/mysqlnd_vio.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,29 @@ MYSQLND_METHOD(mysqlnd_vio, open_pipe)(MYSQLND_VIO * const vio, const MYSQLND_CS
145145
SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown error while connecting");
146146
DBG_RETURN(NULL);
147147
}
148+
149+
if (persistent) {
150+
/* This is a similar hack as for mysqlnd_vio::open_tcp_or_unix.
151+
* The main difference here is that we have no access to the hashed key.
152+
* We can however perform a loop over the persistent resource list to find
153+
* which one corresponds to our newly allocated stream.
154+
* This loop is pretty cheap because it will normally always be the first hit
155+
* when we loop backwards over the list. */
156+
Bucket *bucket;
157+
/* Use a bucket loop to make deletion cheap. */
158+
ZEND_HASH_MAP_REVERSE_FOREACH_BUCKET(&EG(persistent_list), bucket) {
159+
zend_resource *current_res = Z_RES(bucket->val);
160+
if (current_res->ptr == net_stream) {
161+
dtor_func_t origin_dtor = EG(persistent_list).pDestructor;
162+
EG(persistent_list).pDestructor = NULL;
163+
zend_hash_del_bucket(&EG(persistent_list), bucket);
164+
EG(persistent_list).pDestructor = origin_dtor;
165+
pefree(current_res, 1);
166+
break;
167+
}
168+
} ZEND_HASH_FOREACH_END();
169+
}
170+
148171
mysqlnd_fixup_regular_list(net_stream);
149172

150173
DBG_RETURN(net_stream);

0 commit comments

Comments
 (0)