summaryrefslogtreecommitdiff
path: root/ext/mysqlnd/mysqlnd_result.c
diff options
context:
space:
mode:
authorJohannes Schlüter <johannes@php.net>2014-01-21 16:28:30 +0100
committerJohannes Schlüter <johannes@php.net>2014-01-21 16:28:30 +0100
commit2311ba7d3ff08d27bd7d4b87b51a0f96c5d62d12 (patch)
tree0cd92c2c6af31eea71e0e2fe4c1a884d6c0b182f /ext/mysqlnd/mysqlnd_result.c
parent2bd68bf03940769cbd59e5876935147291fd4017 (diff)
downloadphp-git-2311ba7d3ff08d27bd7d4b87b51a0f96c5d62d12.tar.gz
Fix bug #66283 (Segmentation fault after memory_limit)
There are situations where mysqlnd dupliates zvals while freeing result sets. If the memory_limit is reached during this operation the engine will bailout. This patch makes sure that a later attempt (during RSHIUTDOWN) won't cause a double free, instead we rely on the engine to free emalloc()ed memory after bailout.
Diffstat (limited to 'ext/mysqlnd/mysqlnd_result.c')
-rw-r--r--ext/mysqlnd/mysqlnd_result.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index cb15657601..0814926483 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -198,9 +198,11 @@ MYSQLND_METHOD(mysqlnd_res, free_buffered_data)(MYSQLND_RES * result TSRMLS_DC)
if (set->data) {
unsigned int copy_on_write_performed = 0;
unsigned int copy_on_write_saved = 0;
+ zval **data = set->data;
+ set->data = NULL; /* prevent double free if following loop is interrupted */
for (row = set->row_count - 1; row >= 0; row--) {
- zval **current_row = set->data + row * field_count;
+ zval **current_row = data + row * field_count;
MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row];
int64_t col;
@@ -222,8 +224,7 @@ MYSQLND_METHOD(mysqlnd_res, free_buffered_data)(MYSQLND_RES * result TSRMLS_DC)
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_COPY_ON_WRITE_PERFORMED, copy_on_write_performed,
STAT_COPY_ON_WRITE_SAVED, copy_on_write_saved);
- mnd_efree(set->data);
- set->data = NULL;
+ mnd_efree(data);
}
if (set->row_buffers) {