Skip to content

Commit c04565a

Browse files
committed
Factor common code out into mysqlnd_fixup_regular_list()
This prevents the code from getting desynced again, which was the reason for the leak of GH-10599.
1 parent e98c7ee commit c04565a

File tree

1 file changed

+16
-23
lines changed

1 file changed

+16
-23
lines changed

ext/mysqlnd/mysqlnd_vio.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,27 @@ MYSQLND_METHOD(mysqlnd_vio, network_write)(MYSQLND_VIO * const vio, const zend_u
112112
}
113113
/* }}} */
114114

115+
static void mysqlnd_fixup_regular_list(php_stream *net_stream)
116+
{
117+
/*
118+
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
119+
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
120+
unregistered until the script ends. So, we need to take care of that.
121+
*/
122+
dtor_func_t origin_dtor = EG(regular_list).pDestructor;
123+
EG(regular_list).pDestructor = NULL;
124+
zend_hash_index_del(&EG(regular_list), net_stream->res->handle);
125+
EG(regular_list).pDestructor = origin_dtor;
126+
efree(net_stream->res);
127+
net_stream->res = NULL;
128+
}
115129

116130
/* {{{ mysqlnd_vio::open_pipe */
117131
static php_stream *
118132
MYSQLND_METHOD(mysqlnd_vio, open_pipe)(MYSQLND_VIO * const vio, const MYSQLND_CSTRING scheme, const bool persistent,
119133
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info)
120134
{
121135
unsigned int streams_options = 0;
122-
dtor_func_t origin_dtor;
123136
php_stream * net_stream = NULL;
124137

125138
DBG_ENTER("mysqlnd_vio::open_pipe");
@@ -132,17 +145,7 @@ MYSQLND_METHOD(mysqlnd_vio, open_pipe)(MYSQLND_VIO * const vio, const MYSQLND_CS
132145
SET_CLIENT_ERROR(error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown error while connecting");
133146
DBG_RETURN(NULL);
134147
}
135-
/*
136-
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
137-
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
138-
unregistered until the script ends. So, we need to take care of that.
139-
*/
140-
origin_dtor = EG(regular_list).pDestructor;
141-
EG(regular_list).pDestructor = NULL;
142-
zend_hash_index_del(&EG(regular_list), net_stream->res->handle); /* ToDO: should it be res->handle, do streams register with addref ?*/
143-
EG(regular_list).pDestructor = origin_dtor;
144-
efree(net_stream->res);
145-
net_stream->res = NULL;
148+
mysqlnd_fixup_regular_list(net_stream);
146149

147150
DBG_RETURN(net_stream);
148151
}
@@ -224,17 +227,7 @@ MYSQLND_METHOD(mysqlnd_vio, open_tcp_or_unix)(MYSQLND_VIO * const vio, const MYS
224227
mnd_sprintf_free(hashed_details);
225228
}
226229

227-
/*
228-
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
229-
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
230-
unregistered until the script ends. So, we need to take care of that.
231-
*/
232-
origin_dtor = EG(regular_list).pDestructor;
233-
EG(regular_list).pDestructor = NULL;
234-
zend_hash_index_del(&EG(regular_list), net_stream->res->handle); /* ToDO: should it be res->handle, do streams register with addref ?*/
235-
efree(net_stream->res);
236-
net_stream->res = NULL;
237-
EG(regular_list).pDestructor = origin_dtor;
230+
mysqlnd_fixup_regular_list(net_stream);
238231
DBG_RETURN(net_stream);
239232
}
240233
/* }}} */

0 commit comments

Comments
 (0)