Bug #39438 (Fatal error: Out of memory)

This commit is contained in:
Dmitry Stogov 2006-12-01 20:01:50 +00:00
parent e70d7cfc90
commit abc5bb5f61
3 changed files with 57 additions and 11 deletions

1
NEWS
View file

@ -81,6 +81,7 @@ PHP NEWS
- Fixed bug #39454 (Returning a SOAP array segfaults PHP). (Dmitry)
- Fixed bug #39445 (Calling debug_backtrace() in the __toString() function
produces a crash). (Dmitry)
- Fixed bug #39438 (Fatal error: Out of memory). (Dmitry)
- Fixed bug #39414 (Syntax error while compiling with Sun Workshop Complier).
(Johannes)
- Fixed bug #39398 (Booleans are not automatically translated to integers).

45
Zend/tests/bug39438.phpt Executable file
View file

@ -0,0 +1,45 @@
--TEST--
Bug #39438 (Fatal error: Out of memory)
--INI--
memory_limit=16M
--FILE--
<?php
$i=0;
$test2=array(
'a1_teasermenu' => 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

View file

@ -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;
@ -1098,10 +1102,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);
@ -1154,16 +1156,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;
}
}