From: Dmitry Stogov Date: Fri, 1 Dec 2006 20:02:00 +0000 (+0000) Subject: Bug #39438 (Fatal error: Out of memory) X-Git-Tag: RELEASE_1_0_0RC1~855 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef3df1e6ff15c7cd927d99d6504a78f2a608699b;p=php Bug #39438 (Fatal error: Out of memory) --- diff --git a/Zend/tests/bug39438.phpt b/Zend/tests/bug39438.phpt new file mode 100755 index 0000000000..e1ed8e8866 --- /dev/null +++ b/Zend/tests/bug39438.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug #39438 (Fatal error: Out of memory) +--INI-- +memory_limit=16M +--FILE-- + array( + 'downloadcounter' => 2777, + 'versions' => array( + '0.1.0' => array ( + 'title' => 'A1 Teasermenu', + 'description' => 'Displays a teaser for advanced subpages or a selection of advanced pages', + 'state' => 'stable', + 'reviewstate' => 0, + 'category' => 'plugin', + 'downloadcounter' => 2787, + 'lastuploaddate' => 1088427240, + 'dependencies' => array ( + 'depends' => array( + 'typo3' =>'', + 'php' =>'', + 'cms' => '' + ), + 'conflicts' => array('' =>'') + ), + 'authorname' => 'Mirko Balluff', + 'authoremail' => 'balluff@amt1.de', + 'ownerusername' => 'amt1', + 't3xfilemd5' => '3a4ec198b6ea8d0bc2d69d9b7400398f', + ) + ) + ) +); +$test=array(); +while($i<1200) { + $test[]=$test2; + $i++; +} +$out=serialize($test); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 3c869d243c..dff66ba52c 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -472,6 +472,10 @@ static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_blo } } else { prev = &heap->free_buckets[0]; + while (prev->next_free_block != &heap->free_buckets[0] && + ZEND_MM_FREE_BLOCK_SIZE(prev->next_free_block) < size) { + prev = prev->next_free_block; + } } next = prev->next_free_block; mm_block->prev_free_block = prev; @@ -1096,10 +1100,8 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) { - size_t true_size, best_size = 0x7fffffff; zend_mm_free_block *p, *end, *best_fit = NULL; - - true_size = ZEND_MM_TRUE_SIZE(size); + size_t true_size = ZEND_MM_TRUE_SIZE(size); if (ZEND_MM_SMALL_SIZE(true_size)) { size_t index = ZEND_MM_BUCKET_INDEX(true_size); @@ -1152,16 +1154,14 @@ static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D end = &heap->free_buckets[0]; for (p = end->next_free_block; p != end; p = p->next_free_block) { - size_t s = ZEND_MM_FREE_BLOCK_SIZE(p); - if (s > true_size) { - if (s < best_size) { /* better fit */ + if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size) { + if (ZEND_MM_IS_FIRST_BLOCK(p) || + !ZEND_MM_IS_FIRST_BLOCK(ZEND_MM_PREV_BLOCK(p)) || + !ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_NEXT_BLOCK(p)) || + p->next_free_block == end) { best_fit = p; - best_size = s; + goto zend_mm_finished_searching_for_block; } - } else if (s == true_size) { - /* Found "big" free block of exactly the same size */ - best_fit = p; - goto zend_mm_finished_searching_for_block; } }