Skip to content

Commit

Permalink
Fix leak when breaking out of FilesystemIterator
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Feb 15, 2021
1 parent c34c523 commit 44a80b6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 19 deletions.
22 changes: 3 additions & 19 deletions ext/spl/spl_directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
/* }}} */

Expand Down Expand Up @@ -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);
}
/* }}} */

Expand Down
12 changes: 12 additions & 0 deletions ext/spl/tests/filesystemiterator_leak.phpt
Original file line number Diff line number Diff line change
@@ -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===

0 comments on commit 44a80b6

Please sign in to comment.