Skip to content

Commit f7b1238

Browse files
committed
Handle out of order destruction of RecursiveIteratorIterator
1 parent 29b8269 commit f7b1238

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

ext/spl/spl_iterators.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,16 +160,18 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter)
160160
spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(&iter->intern.data);
161161
zend_object_iterator *sub_iter;
162162

163-
while (object->level > 0) {
164-
if (!Z_ISUNDEF(object->iterators[object->level].zobject)) {
165-
sub_iter = object->iterators[object->level].iterator;
166-
zend_iterator_dtor(sub_iter);
167-
zval_ptr_dtor(&object->iterators[object->level].zobject);
163+
if (object->iterators) {
164+
while (object->level > 0) {
165+
if (!Z_ISUNDEF(object->iterators[object->level].zobject)) {
166+
sub_iter = object->iterators[object->level].iterator;
167+
zend_iterator_dtor(sub_iter);
168+
zval_ptr_dtor(&object->iterators[object->level].zobject);
169+
}
170+
object->level--;
168171
}
169-
object->level--;
172+
object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
173+
object->level = 0;
170174
}
171-
object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
172-
object->level = 0;
173175

174176
zval_ptr_dtor(&iter->intern.data);
175177
}
@@ -905,6 +907,7 @@ static void spl_RecursiveIteratorIterator_free_storage(zend_object *_object)
905907
object->level--;
906908
}
907909
efree(object->iterators);
910+
object->iterators = NULL;
908911
}
909912

910913
zend_object_std_dtor(&object->std);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Handle object_iterator being destroyed before the RecursiveIteratorIterator object
3+
--FILE--
4+
<?php
5+
6+
$dummy = new stdClass; // Dummy object to control object store ordering
7+
$it = new RecursiveIteratorIterator(new RecursiveArrayIterator([1]));
8+
unset($dummy);
9+
foreach ($it as $v) {
10+
eval('class self {}'); // Cause a bailout.
11+
}
12+
?>
13+
--EXPECTF--
14+
Fatal error: Cannot use 'self' as class name as it is reserved in %s on line %d

0 commit comments

Comments
 (0)