Skip to content

Commit abc5bb5

Browse files
committed
Bug #39438 (Fatal error: Out of memory)
1 parent e70d7cf commit abc5bb5

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ PHP NEWS
8181
- Fixed bug #39454 (Returning a SOAP array segfaults PHP). (Dmitry)
8282
- Fixed bug #39445 (Calling debug_backtrace() in the __toString() function
8383
produces a crash). (Dmitry)
84+
- Fixed bug #39438 (Fatal error: Out of memory). (Dmitry)
8485
- Fixed bug #39414 (Syntax error while compiling with Sun Workshop Complier).
8586
(Johannes)
8687
- Fixed bug #39398 (Booleans are not automatically translated to integers).

Zend/tests/bug39438.phpt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
--TEST--
2+
Bug #39438 (Fatal error: Out of memory)
3+
--INI--
4+
memory_limit=16M
5+
--FILE--
6+
<?php
7+
$i=0;
8+
$test2=array(
9+
'a1_teasermenu' => array(
10+
'downloadcounter' => 2777,
11+
'versions' => array(
12+
'0.1.0' => array (
13+
'title' => 'A1 Teasermenu',
14+
'description' => 'Displays a teaser for advanced subpages or a selection of advanced pages',
15+
'state' => 'stable',
16+
'reviewstate' => 0,
17+
'category' => 'plugin',
18+
'downloadcounter' => 2787,
19+
'lastuploaddate' => 1088427240,
20+
'dependencies' => array (
21+
'depends' => array(
22+
'typo3' =>'',
23+
'php' =>'',
24+
'cms' => ''
25+
),
26+
'conflicts' => array('' =>'')
27+
),
28+
'authorname' => 'Mirko Balluff',
29+
'authoremail' => 'balluff@amt1.de',
30+
'ownerusername' => 'amt1',
31+
't3xfilemd5' => '3a4ec198b6ea8d0bc2d69d9b7400398f',
32+
)
33+
)
34+
)
35+
);
36+
$test=array();
37+
while($i<1200) {
38+
$test[]=$test2;
39+
$i++;
40+
}
41+
$out=serialize($test);
42+
echo "ok\n";
43+
?>
44+
--EXPECT--
45+
ok

Zend/zend_alloc.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,10 @@ static inline void zend_mm_add_to_free_list(zend_mm_heap *heap, zend_mm_free_blo
472472
}
473473
} else {
474474
prev = &heap->free_buckets[0];
475+
while (prev->next_free_block != &heap->free_buckets[0] &&
476+
ZEND_MM_FREE_BLOCK_SIZE(prev->next_free_block) < size) {
477+
prev = prev->next_free_block;
478+
}
475479
}
476480
next = prev->next_free_block;
477481
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
10981102

10991103
static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
11001104
{
1101-
size_t true_size, best_size = 0x7fffffff;
11021105
zend_mm_free_block *p, *end, *best_fit = NULL;
1103-
1104-
true_size = ZEND_MM_TRUE_SIZE(size);
1106+
size_t true_size = ZEND_MM_TRUE_SIZE(size);
11051107

11061108
if (ZEND_MM_SMALL_SIZE(true_size)) {
11071109
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
11541156

11551157
end = &heap->free_buckets[0];
11561158
for (p = end->next_free_block; p != end; p = p->next_free_block) {
1157-
size_t s = ZEND_MM_FREE_BLOCK_SIZE(p);
1158-
if (s > true_size) {
1159-
if (s < best_size) { /* better fit */
1159+
if (ZEND_MM_FREE_BLOCK_SIZE(p) >= true_size) {
1160+
if (ZEND_MM_IS_FIRST_BLOCK(p) ||
1161+
!ZEND_MM_IS_FIRST_BLOCK(ZEND_MM_PREV_BLOCK(p)) ||
1162+
!ZEND_MM_IS_GUARD_BLOCK(ZEND_MM_NEXT_BLOCK(p)) ||
1163+
p->next_free_block == end) {
11601164
best_fit = p;
1161-
best_size = s;
1165+
goto zend_mm_finished_searching_for_block;
11621166
}
1163-
} else if (s == true_size) {
1164-
/* Found "big" free block of exactly the same size */
1165-
best_fit = p;
1166-
goto zend_mm_finished_searching_for_block;
11671167
}
11681168
}
11691169

0 commit comments

Comments
 (0)