Commit:    3960def881c5e29daa18c914cf95e1e978db053b
Author:    Gustavo André dos Santos Lopes <cataphr...@php.net>         Fri, 23 
Mar 2012 09:42:05 +0000
Parents:   85725337d5aa7d6cbe69be8c4ce83656f0aca885
Branches:  PHP-5.4 PHP-5.3 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=3960def881c5e29daa18c914cf95e1e978db053b

Log:
Fixed bug #61482, caused by the fix to bug #61418.

Turns out I'd forgotten to also update the destructor for the iterator
returned by DirectoryIterator.
The iterator for DirectoryIterator maintains the same ->current pointer
throughout its existence (the DirectoryIterator itself) and returns it
(the same object) everytime a value is requested from the iterator.
Moving forward the iterator only changes the object. Previous code
added two references to the object in get_iterator on the account of
1) the iterator memory living in its DirectoryIterator object and
2) the object being stored in iterator->current. This seems to be
unnecessary. Iterators are not responsible for incrementing the refcount
of the values they yield, that's up to the caller (the engine). What
matters for the iterator is that the object exists as long as the
iterator exists and this can be guaranteed by incremented the refcount
only once. Consequently, I only add one reference in get_iterator
(and reclaim it in the iterator destructor).

Bugs:
https://bugs.php.net/61482
https://bugs.php.net/61418

Changed paths:
  M  ext/spl/spl_directory.c


Diff:
3960def881c5e29daa18c914cf95e1e978db053b
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index fb19823..04da4e6 100755
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -1655,13 +1655,16 @@ zend_object_iterator 
*spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
 static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
 {
        spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter;
-       zval *zfree = (zval*)iterator->intern.data;
 
-       iterator->intern.data = NULL; /* mark as unused */
-       zval_ptr_dtor(&iterator->current);
-       if (zfree) {
-               zval_ptr_dtor(&zfree);
+       if (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 NULL.
+        * We don't even need to destroy iterator->current as we didn't add a
+        * reference to it in move_forward or get_iterator */
 }
 /* }}} */


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to