Skip to content

Commit

Permalink
Fix uouv on oom on object allocation
Browse files Browse the repository at this point in the history
We should initialize object handlers before trying to allocate more memory,
because if we OOM we'll look for the free_obj handler which has not been
initialized. Furthermore, free_obj can run before the object is fully
initialized, requiring guards for potentially unset fields.

Fixes GH-11734
  • Loading branch information
iluuu1994 committed Aug 2, 2023
1 parent 66b359e commit df03193
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Zend/tests/new_oom.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

$mb_used = (int) ceil(memory_get_usage() / (1024 ** 2));
ini_set('memory_limit', ($mb_used + 1) . 'M');

$class = $argv[1];
$objects = [];

try {
while (true) {
$rc = new ReflectionClass($class);
$objects[] = $rc->newInstanceWithoutConstructor();
}
} catch (Throwable) {
}
24 changes: 24 additions & 0 deletions Zend/tests/new_oom.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
Test OOM on new of each class
--SKIPIF--
<?php
if (getenv("SKIP_SLOW_TESTS")) die('skip slow test');
?>
--FILE--
<?php

$file = __DIR__ . '/new_oom.inc';
$php = PHP_BINARY;

foreach (get_declared_classes() as $class) {
echo "Class $class\n";
$output = shell_exec("$php $file $class");
if ($output && preg_match('(^\nFatal error: Allowed memory size of [0-9]+ bytes exhausted[^\r\n]* \(tried to allocate [0-9]+ bytes\) in [^\r\n]+ on line [0-9]+$)', $output) !== 1) {
echo $output;
}
}

?>
===DONE===
--EXPECT--
===DONE===
5 changes: 5 additions & 0 deletions ext/spl/spl_heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,11 @@ static spl_ptr_heap *spl_ptr_heap_clone(spl_ptr_heap *from) { /* {{{ */
static void spl_ptr_heap_destroy(spl_ptr_heap *heap) { /* {{{ */
int i;

/* Heap might be null if we OOMed during object initialization. */
if (!heap) {
return;
}

for (i = 0; i < heap->count; ++i) {
heap->dtor(spl_heap_elem(heap, i));
}
Expand Down

0 comments on commit df03193

Please sign in to comment.