From 3adbafeef73a3b1df01222cd7a98afe4c4e007c5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 24 Sep 2021 13:17:15 +0200 Subject: [PATCH] Fix leak when iterating uninitialized RecursiveIteratorIterator --- ext/spl/spl_iterators.c | 8 +++----- ...ecursiveIteratorIterator_not_initialized.phpt | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 251f5999a38..73c6a87e213 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -441,20 +441,18 @@ static const zend_object_iterator_funcs spl_recursive_it_iterator_funcs = { static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, zval *zobject, int by_ref) { - spl_recursive_it_iterator *iterator; - spl_recursive_it_object *object; - if (by_ref) { zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } - iterator = emalloc(sizeof(spl_recursive_it_iterator)); - object = Z_SPLRECURSIVE_IT_P(zobject); + + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(zobject); if (object->iterators == NULL) { zend_throw_error(NULL, "Object is not initialized"); return NULL; } + spl_recursive_it_iterator *iterator = emalloc(sizeof(spl_recursive_it_iterator)); zend_iterator_init((zend_object_iterator*)iterator); ZVAL_OBJ_COPY(&iterator->intern.data, Z_OBJ_P(zobject)); diff --git a/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt b/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt new file mode 100644 index 00000000000..4e90692843d --- /dev/null +++ b/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt @@ -0,0 +1,16 @@ +--TEST-- +Iterating an uninitialized RecursiveIteratorIterator +--FILE-- +newInstanceWithoutConstructor(); +try { + foreach ($it as $v) {} +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Object is not initialized