Skip to content

Commit 44a80b6

Browse files
committed
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.
1 parent c34c523 commit 44a80b6

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

ext/spl/spl_directory.c

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,15 +1677,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
16771677
static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter)
16781678
{
16791679
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1680-
1681-
if (!Z_ISUNDEF(iterator->intern.data)) {
1682-
zval *object = &iterator->intern.data;
1683-
zval_ptr_dtor(object);
1684-
}
1685-
/* Otherwise we were called from the owning object free storage handler as
1686-
* it sets iterator->intern.data to IS_UNDEF.
1687-
* We don't even need to destroy iterator->current as we didn't add a
1688-
* reference to it in move_forward or get_iterator */
1680+
zval_ptr_dtor(&iterator->intern.data);
16891681
}
16901682
/* }}} */
16911683

@@ -1747,16 +1739,8 @@ static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter)
17471739
static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter)
17481740
{
17491741
spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
1750-
1751-
if (!Z_ISUNDEF(iterator->intern.data)) {
1752-
zval *object = &iterator->intern.data;
1753-
zval_ptr_dtor(object);
1754-
} else {
1755-
if (!Z_ISUNDEF(iterator->current)) {
1756-
zval_ptr_dtor(&iterator->current);
1757-
ZVAL_UNDEF(&iterator->current);
1758-
}
1759-
}
1742+
zval_ptr_dtor(&iterator->intern.data);
1743+
zval_ptr_dtor(&iterator->current);
17601744
}
17611745
/* }}} */
17621746

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Don't leak when breaking from FilesystemIterator
3+
--FILE--
4+
<?php
5+
$iterator = new FilesystemIterator(__DIR__);
6+
foreach ($iterator as $value) {
7+
break;
8+
}
9+
?>
10+
===DONE===
11+
--EXPECT--
12+
===DONE===

0 commit comments

Comments
 (0)