summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd_result.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2019-01-14 13:59:30 +0300
committerDmitry Stogov <dmitry@zend.com>2019-01-14 13:59:30 +0300
commit1a306cc9a1679a758c859731a78429429830a439 (patch)
treea9ea76970e6c23778d58c642d683e066ee246e6d /ext/mysqlnd/mysqlnd_result.c
parent5c3b17ca68b97ed3ad568eb7fd03ac2edb42f332 (diff)
downloadphp-git-1a306cc9a1679a758c859731a78429429830a439.tar.gz
Fixed bug #77308 (Unbuffered queries memory leak)
Diffstat (limited to 'ext/mysqlnd/mysqlnd_result.c')
-rw-r--r--ext/mysqlnd/mysqlnd_result.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index 38fe116686..201e314f7d 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -651,6 +651,7 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
MYSQLND_PACKET_ROW *row_packet = result->unbuf->row_packet;
MYSQLND_RES_METADATA * const meta = result->meta;
MYSQLND_CONN_DATA * const conn = result->conn;
+ void *checkpoint;
DBG_ENTER("mysqlnd_result_unbuffered::fetch_row_c");
@@ -670,6 +671,9 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
/* Let the row packet fill our buffer and skip additional mnd_malloc + memcpy */
row_packet->skip_extraction = FALSE;
+ checkpoint = result->memory_pool->checkpoint;
+ mysqlnd_mempool_save_state(result->memory_pool);
+
/*
If we skip rows (row == NULL) we have to
result->m.unbuffered_free_last_data() before it. The function returns always true.
@@ -694,6 +698,8 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
conn->options->int_and_float_native,
conn->stats);
if (PASS != rc) {
+ mysqlnd_mempool_restore_state(result->memory_pool);
+ result->memory_pool->checkpoint = checkpoint;
DBG_RETURN(FAIL);
}
{
@@ -757,6 +763,9 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row_c)(MYSQLND_RES * result, voi
result->unbuf->m.free_last_data(result->unbuf, conn->stats);
}
+ mysqlnd_mempool_restore_state(result->memory_pool);
+ result->memory_pool->checkpoint = checkpoint;
+
DBG_INF_FMT("ret=%s fetched=%u", ret == PASS? "PASS":"FAIL", *fetched_anything);
DBG_RETURN(PASS);
}