From: Dmitry Stogov Date: Thu, 14 Feb 2008 14:47:25 +0000 (+0000) Subject: Fixed bug #44069 (Huge memory usage with concatenation using . instead of .=) X-Git-Tag: php-5.2.6RC1~72 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=af3aecb688ef48ac59b5917431a2e189b68a5cf6;p=php Fixed bug #44069 (Huge memory usage with concatenation using . instead of .=) --- diff --git a/NEWS b/NEWS index 5655e24f86..9e39610d42 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,8 @@ PHP NEWS which to group by data is specified. (Ilia) - Upgraded PCRE to version 7.6 (Nuno) +- Fixed bug #44069 (Huge memory usage with concatenation using . instead of + .=). (Dmitry) - Fixed bug #44046 (crash inside array_slice() function with an invalid by-ref offset). (Ilia) - Fixed bug #44028 (crash inside stream_socket_enable_crypto() when enabling diff --git a/Zend/tests/bug44069.phpt b/Zend/tests/bug44069.phpt new file mode 100644 index 0000000000..75beaafed7 --- /dev/null +++ b/Zend/tests/bug44069.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #44069 (Huge memory usage with concatenation using . instead of .=) +--FILE-- + +--EXPECT-- +ok diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 8c53611e01..d48c29c6ec 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -1747,6 +1747,7 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D size_t remaining_size; size_t segment_size; zend_mm_segment *segment; + int keep_rest = 0; if (EXPECTED(ZEND_MM_SMALL_SIZE(true_size))) { size_t index = ZEND_MM_BUCKET_INDEX(true_size); @@ -1815,6 +1816,7 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D segment must have header "size" and trailer "guard" block */ segment_size = true_size + ZEND_MM_ALIGNED_SEGMENT_SIZE + ZEND_MM_ALIGNED_HEADER_SIZE; segment_size = (segment_size + (heap->block_size-1)) & ~(heap->block_size-1); + keep_rest = 1; } else { segment_size = heap->block_size; } @@ -1894,7 +1896,11 @@ zend_mm_finished_searching_for_block: ZEND_MM_BLOCK(new_free_block, ZEND_MM_FREE_BLOCK, remaining_size); /* add the new free block to the free list */ - zend_mm_add_to_free_list(heap, new_free_block); + if (EXPECTED(!keep_rest)) { + zend_mm_add_to_free_list(heap, new_free_block); + } else { + zend_mm_add_to_rest_list(heap, new_free_block); + } } ZEND_MM_SET_DEBUG_INFO(best_fit, size, 1, 1);