Fix leak when breaking out of FilesystemIterator

We need to always destroy current, not just when iter.data is not
set.

Take this opportunity to clean up the iterator destructor code a
bit, to remove redundant checks and incorrect comments.
This commit is contained in:
Nikita Popov 2021-02-15 10:36:48 +01:00
parent c34c523467
commit 44a80b64b9
2 changed files with 15 additions and 19 deletions

View File

@ -1677,15 +1677,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter)
{
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
if (!Z_ISUNDEF(iterator->intern.data)) {
zval *object = &iterator->intern.data;
zval_ptr_dtor(object);
}
/* Otherwise we were called from the owning object free storage handler as
* it sets iterator->intern.data to IS_UNDEF.
* We don't even need to destroy iterator->current as we didn't add a
* reference to it in move_forward or get_iterator */
zval_ptr_dtor(&iterator->intern.data);
}
/* }}} */
@ -1747,16 +1739,8 @@ static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter)
static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter)
{
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
if (!Z_ISUNDEF(iterator->intern.data)) {
zval *object = &iterator->intern.data;
zval_ptr_dtor(object);
} else {
if (!Z_ISUNDEF(iterator->current)) {
zval_ptr_dtor(&iterator->current);
ZVAL_UNDEF(&iterator->current);
}
}
zval_ptr_dtor(&iterator->intern.data);
zval_ptr_dtor(&iterator->current);
}
/* }}} */

View File

@ -0,0 +1,12 @@
--TEST--
Don't leak when breaking from FilesystemIterator
--FILE--
<?php
$iterator = new FilesystemIterator(__DIR__);
foreach ($iterator as $value) {
break;
}
?>
===DONE===
--EXPECT--
===DONE===