Skip to content

Commit f534df7

Browse files
committed
Fix inconsistencies
- memory allocated with spprintf, or likes, outside of mysqlnd's allocator functions should not be freed by the mysqlnd's allocator (a wrapper around emalloc/malloc). - memory allocated by the mysqlnd's allocator should only be freed by it. - add a mode to track memory usage (malloc/free)
1 parent a712d9c commit f534df7

File tree

9 files changed

+186
-145
lines changed

9 files changed

+186
-145
lines changed

ext/mysqlnd/mysqlnd.c

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
529529
db = "";
530530
db_len = 0;
531531
}
532+
532533
host_len = strlen(host);
533534
{
534535
char * transport = NULL;
@@ -553,7 +554,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
553554
DBG_INF_FMT("transport=%s", transport);
554555
conn->scheme = mnd_pestrndup(transport, transport_len, conn->persistent);
555556
conn->scheme_len = transport_len;
556-
efree(transport);
557+
efree(transport); /* allocated by spprintf */
557558
transport = NULL;
558559
}
559560

@@ -643,6 +644,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
643644
}
644645
} else {
645646
CONN_SET_STATE(conn, CONN_READY);
647+
646648
if (!self_alloced && saved_compression) {
647649
conn->net->compressed = TRUE;
648650
}
@@ -662,16 +664,14 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
662664
conn->connect_or_select_db_len = db_len;
663665

664666
if (!unix_socket) {
665-
char *p;
666667

667668
conn->host = mnd_pestrdup(host, conn->persistent);
668669
conn->host_len = strlen(conn->host);
669-
spprintf(&p, 0, "%s via TCP/IP", conn->host);
670-
if (conn->persistent) {
671-
conn->host_info = mnd_pestrdup(p, 1);
672-
mnd_efree(p);
673-
} else {
674-
conn->host_info = p;
670+
{
671+
char *p;
672+
spprintf(&p, 0, "%s via TCP/IP", conn->host);
673+
conn->host_info = mnd_pestrdup(p, conn->persistent);
674+
efree(p); /* allocated by spprintf */
675675
}
676676
} else {
677677
conn->unix_socket = mnd_pestrdup(socket, conn->persistent);
@@ -693,10 +693,6 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
693693
SET_EMPTY_ERROR(conn->error_info);
694694

695695
mysqlnd_local_infile_default(conn);
696-
{
697-
unsigned int buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/
698-
conn->m->set_client_option(conn, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
699-
}
700696

701697
MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1);
702698
if (reconnect) {
@@ -707,6 +703,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
707703
}
708704

709705
DBG_INF_FMT("connection_id=%llu", conn->thread_id);
706+
710707
#if PHP_MAJOR_VERSION >= 6
711708
{
712709
unsigned int as_unicode = 1;
@@ -715,7 +712,6 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND *conn,
715712
DBG_INF("unicode set");
716713
}
717714
#endif
718-
719715
if (conn->options.init_commands) {
720716
int current_command = 0;
721717
for (; current_command < conn->options.num_commands; ++current_command) {
@@ -773,7 +769,7 @@ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn,
773769
unsigned int mysql_flags
774770
TSRMLS_DC)
775771
{
776-
enum_func_status ret;
772+
enum_func_status ret = FAIL;
777773
zend_bool self_alloced = FALSE;
778774

779775
DBG_ENTER("mysqlnd_connect");
@@ -1139,7 +1135,7 @@ MYSQLND_METHOD(mysqlnd_conn, list_method)(MYSQLND *conn, const char *query, cons
11391135
result = conn->m->store_result(conn TSRMLS_CC);
11401136
}
11411137
if (show_query != query) {
1142-
mnd_efree(show_query);
1138+
efree(show_query); /* allocated by spprintf */
11431139
}
11441140
DBG_RETURN(result);
11451141
}
@@ -1225,7 +1221,7 @@ MYSQLND_METHOD(mysqlnd_conn, select_db)(MYSQLND * const conn, const char * const
12251221
SET_ERROR_AFF_ROWS(conn);
12261222
if (ret == PASS) {
12271223
if (conn->connect_or_select_db) {
1228-
pefree(conn->connect_or_select_db, conn->persistent);
1224+
mnd_pefree(conn->connect_or_select_db, conn->persistent);
12291225
}
12301226
conn->connect_or_select_db = mnd_pestrndup(db, db_len, conn->persistent);
12311227
conn->connect_or_select_db_len = db_len;
@@ -1275,10 +1271,9 @@ MYSQLND_METHOD(mysqlnd_conn, stat)(MYSQLND *conn, char **message, unsigned int *
12751271
if (FAIL == (ret = PACKET_READ(stats_header, conn))) {
12761272
DBG_RETURN(FAIL);
12771273
}
1278-
*message = stats_header->message;
1274+
/* will be freed by Zend, thus don't use the mnd_ allocator */
1275+
*message = estrndup(stats_header->message, stats_header->message_len);
12791276
*message_len = stats_header->message_len;
1280-
/* Ownership transfer */
1281-
stats_header->message = NULL;
12821277
PACKET_FREE(stats_header);
12831278

12841279
DBG_INF(*message);
@@ -1343,7 +1338,7 @@ MYSQLND_METHOD(mysqlnd_conn, set_charset)(MYSQLND * const conn, const char * con
13431338
} else {
13441339
conn->charset = charset;
13451340
}
1346-
mnd_efree(query);
1341+
efree(query); /* allocated by spprintf */
13471342

13481343
DBG_INF(ret == PASS? "PASS":"FAIL");
13491344
DBG_RETURN(ret);

0 commit comments

Comments
 (0)