diff options
author | Dmitry Stogov <dmitry@zend.com> | 2019-02-12 10:55:05 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2019-02-12 10:55:05 +0300 |
commit | b6e58dcd2262c30c0657624ca3c372dc90d5a031 (patch) | |
tree | 194854f532c1059bdcbae4a6f5964f8b45c319bf | |
parent | 470f5891d48cad64fd73dbb34775b3bcce1337cf (diff) | |
download | php-git-b6e58dcd2262c30c0657624ca3c372dc90d5a031.tar.gz |
Fixed bug #77599 (Unbuffered queries; native prepared statements memory leak)
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_ps.c | 9 |
2 files changed, 13 insertions, 0 deletions
@@ -18,6 +18,10 @@ PHP NEWS . Fixed bug #77514 (mb_ereg_replace() with trailing backslash adds null byte). (Nikita) +- MySQLnd: + . Fixed bug #77599 (Unbuffered queries; native prepared statements memory + leak). (Dmitry) + - OpenSSL: . Fixed bug #77390 (feof might hang on TLS streams in case of fragmented TLS records). (Abyl Valg, Jakub Zelenka) diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index f3fab43f0c..b2017b9127 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -851,6 +851,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi MYSQLND_PACKET_ROW * row_packet; MYSQLND_CONN_DATA * conn = result->conn; const MYSQLND_RES_METADATA * const meta = result->meta; + void *checkpoint; DBG_ENTER("mysqlnd_stmt_fetch_row_unbuffered"); @@ -873,6 +874,9 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi /* Let the row packet fill our buffer and skip additional malloc + memcpy */ row_packet->skip_extraction = stmt && stmt->result_bind? FALSE:TRUE; + checkpoint = result->memory_pool->checkpoint; + mysqlnd_mempool_save_state(result->memory_pool); + /* If we skip rows (stmt == NULL || stmt->result_bind == NULL) we have to result->unbuf->m.free_last_data() before it. The function returns always true. @@ -895,6 +899,8 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi conn->options->int_and_float_native, conn->stats)) { + mysqlnd_mempool_restore_state(result->memory_pool); + result->memory_pool->checkpoint = checkpoint; DBG_RETURN(FAIL); } @@ -965,6 +971,9 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES * result, void * param, const unsi } } + mysqlnd_mempool_restore_state(result->memory_pool); + result->memory_pool->checkpoint = checkpoint; + DBG_INF_FMT("ret=%s fetched_anything=%u", ret == PASS? "PASS":"FAIL", *fetched_anything); DBG_RETURN(ret); } |