Skip to content

Commit df982da

Browse files
committed
Fix bug #78525
When calling free_result_buffers(), also free field metadata and restore the mempool state to what it was before any allocations have been made. Remove the mempool save/restore logic for the inner result set as this is now handled on a higher level.
1 parent 31f617d commit df982da

File tree

3 files changed

+19
-16
lines changed

3 files changed

+19
-16
lines changed

NEWS

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ PHP NEWS
33
?? ??? ????, PHP 7.3.11
44

55
- Exif :
6-
.Fixed bug #78442 ('Illegal component' on exif_read_data since PHP7)
6+
. Fixed bug #78442 ('Illegal component' on exif_read_data since PHP7)
77
(Kalle)
88

9+
- Mysqlnd:
10+
. Fixed bug #78525 (Memory leak in pdo when reusing native prepared
11+
statements). (Nikita)
12+
913
12 Sep 2019, PHP 7.3.10RC1
1014

1115
- Core:

ext/mysqlnd/mysqlnd_block_alloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ PHPAPI void
200200
mysqlnd_mempool_restore_state(MYSQLND_MEMORY_POOL * pool)
201201
{
202202
DBG_ENTER("mysqlnd_mempool_restore_state");
203+
#if ZEND_DEBUG
204+
ZEND_ASSERT(pool->checkpoint);
205+
#endif
203206
if (pool->checkpoint) {
204207
mysqlnd_arena_release(&pool->arena, pool->checkpoint);
205208
pool->last = NULL;

ext/mysqlnd/mysqlnd_result.c

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,6 @@ MYSQLND_METHOD(mysqlnd_result_unbuffered, free_result)(MYSQLND_RES_UNBUFFERED *
190190
result->row_packet = NULL;
191191
}
192192

193-
mysqlnd_mempool_restore_state(result->result_set_memory_pool);
194-
195193
DBG_VOID_RETURN;
196194
}
197195
/* }}} */
@@ -261,8 +259,6 @@ MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * cons
261259
set->row_buffers = NULL;
262260
}
263261

264-
mysqlnd_mempool_restore_state(set->result_set_memory_pool);
265-
266262
DBG_VOID_RETURN;
267263
}
268264
/* }}} */
@@ -275,6 +271,12 @@ MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES * result)
275271
DBG_ENTER("mysqlnd_res::free_result_buffers");
276272
DBG_INF_FMT("%s", result->unbuf? "unbuffered":(result->stored_data? "buffered":"unknown"));
277273

274+
if (result->meta) {
275+
ZEND_ASSERT(zend_arena_contains(result->memory_pool->arena, result->meta));
276+
result->meta->m->free_metadata(result->meta);
277+
result->meta = NULL;
278+
}
279+
278280
if (result->unbuf) {
279281
result->unbuf->m.free_result(result->unbuf, result->conn? result->conn->stats : NULL);
280282
result->unbuf = NULL;
@@ -283,6 +285,9 @@ MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES * result)
283285
result->stored_data = NULL;
284286
}
285287

288+
mysqlnd_mempool_restore_state(result->memory_pool);
289+
mysqlnd_mempool_save_state(result->memory_pool);
290+
286291
DBG_VOID_RETURN;
287292
}
288293
/* }}} */
@@ -294,12 +299,6 @@ void MYSQLND_METHOD(mysqlnd_res, free_result_contents_internal)(MYSQLND_RES * re
294299
{
295300
DBG_ENTER("mysqlnd_res::free_result_contents_internal");
296301

297-
if (result->meta) {
298-
ZEND_ASSERT(zend_arena_contains(result->memory_pool->arena, result->meta));
299-
result->meta->m->free_metadata(result->meta);
300-
result->meta = NULL;
301-
}
302-
303302
result->m.free_result_buffers(result);
304303

305304
DBG_VOID_RETURN;
@@ -1926,6 +1925,8 @@ mysqlnd_result_init(const unsigned int field_count)
19261925
ret->field_count = field_count;
19271926
ret->m = *mysqlnd_result_get_methods();
19281927

1928+
mysqlnd_mempool_save_state(pool);
1929+
19291930
DBG_RETURN(ret);
19301931
}
19311932
/* }}} */
@@ -1941,7 +1942,6 @@ mysqlnd_result_unbuffered_init(MYSQLND_RES *result, const unsigned int field_cou
19411942

19421943
DBG_ENTER("mysqlnd_result_unbuffered_init");
19431944

1944-
mysqlnd_mempool_save_state(pool);
19451945
ret = pool->get_chunk(pool, alloc_size);
19461946
memset(ret, 0, alloc_size);
19471947

@@ -1976,12 +1976,10 @@ mysqlnd_result_buffered_zval_init(MYSQLND_RES * result, const unsigned int field
19761976

19771977
DBG_ENTER("mysqlnd_result_buffered_zval_init");
19781978

1979-
mysqlnd_mempool_save_state(pool);
19801979
ret = pool->get_chunk(pool, alloc_size);
19811980
memset(ret, 0, alloc_size);
19821981

19831982
if (FAIL == mysqlnd_error_info_init(&ret->error_info, 0)) {
1984-
mysqlnd_mempool_restore_state(pool);
19851983
DBG_RETURN(NULL);
19861984
}
19871985

@@ -2019,12 +2017,10 @@ mysqlnd_result_buffered_c_init(MYSQLND_RES * result, const unsigned int field_co
20192017

20202018
DBG_ENTER("mysqlnd_result_buffered_c_init");
20212019

2022-
mysqlnd_mempool_save_state(pool);
20232020
ret = pool->get_chunk(pool, alloc_size);
20242021
memset(ret, 0, alloc_size);
20252022

20262023
if (FAIL == mysqlnd_error_info_init(&ret->error_info, 0)) {
2027-
mysqlnd_mempool_restore_state(pool);
20282024
DBG_RETURN(NULL);
20292025
}
20302026

0 commit comments

Comments
 (0)