cataphract Sun, 18 Mar 2012 15:07:20 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=324327
Log: - Fixed bug #61418 (Segmentation fault when DirectoryIterator's or FilesystemIterator's iterators are requested more than once without having had its dtor callback called in between). Bug: https://bugs.php.net/61418 (Assigned) Segmentation foult using FiltesystemIterator & RegexIterator Changed paths: U php/php-src/branches/PHP_5_3/NEWS U php/php-src/branches/PHP_5_3/ext/spl/spl_directory.c A php/php-src/branches/PHP_5_3/ext/spl/tests/bug61418.phpt U php/php-src/branches/PHP_5_4/ext/spl/spl_directory.c A php/php-src/branches/PHP_5_4/ext/spl/tests/bug61418.phpt U php/php-src/trunk/ext/spl/spl_directory.c A php/php-src/trunk/ext/spl/tests/bug61418.phpt
Modified: php/php-src/branches/PHP_5_3/NEWS =================================================================== --- php/php-src/branches/PHP_5_3/NEWS 2012-03-18 13:19:50 UTC (rev 324326) +++ php/php-src/branches/PHP_5_3/NEWS 2012-03-18 15:07:20 UTC (rev 324327) @@ -81,6 +81,9 @@ - SPL . Fixed memory leak when calling SplFileInfo's constructor twice. (Felipe) + . Fixed bug #61418 (Segmentation fault when DirectoryIterator's or + FilesystemIterator's iterators are requested more than once without + having had its dtor callback called in between). (Gustavo) . Fixed bug #61347 (inconsistent isset behavior of Arrayobject). (Laruence) . Fixed bug #61326 (ArrayObject comparison). (Gustavo) Modified: php/php-src/branches/PHP_5_3/ext/spl/spl_directory.c =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/spl_directory.c 2012-03-18 13:19:50 UTC (rev 324326) +++ php/php-src/branches/PHP_5_3/ext/spl/spl_directory.c 2012-03-18 15:07:20 UTC (rev 324327) @@ -120,6 +120,16 @@ spl_filesystem_file_free_line(intern TSRMLS_CC); break; } + + { + zend_object_iterator *iterator; + iterator = (zend_object_iterator*) + spl_filesystem_object_to_iterator(intern); + if (iterator->data != NULL) { + iterator->data = NULL; + iterator->funcs->dtor(iterator TSRMLS_CC); + } + } efree(object); } /* }}} */ @@ -1627,10 +1637,15 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_dir_it_funcs; - iterator->current = object; + /* initialize iterator if it wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_dir_it_funcs; + /* ->current must be initialized; rewind doesn't set it and valid + * doesn't check whether it's set */ + iterator->current = object; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } @@ -1709,15 +1724,15 @@ static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; - zval *zfree = (zval*)iterator->intern.data; - if (iterator->current) { - zval_ptr_dtor(&iterator->current); + if (iterator->intern.data) { + zval *object = iterator->intern.data; + zval_ptr_dtor(&object); + } else { + if (iterator->current) { + zval_ptr_dtor(&iterator->current); + } } - iterator->intern.data = NULL; /* mark as unused */ - /* free twice as we add ref twice */ - zval_ptr_dtor(&zfree); - zval_ptr_dtor(&zfree); } /* }}} */ @@ -1828,10 +1843,12 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_tree_it_funcs; - iterator->current = NULL; + /* initialize iterator if wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_tree_it_funcs; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } Added: php/php-src/branches/PHP_5_3/ext/spl/tests/bug61418.phpt =================================================================== --- php/php-src/branches/PHP_5_3/ext/spl/tests/bug61418.phpt (rev 0) +++ php/php-src/branches/PHP_5_3/ext/spl/tests/bug61418.phpt 2012-03-18 15:07:20 UTC (rev 324327) @@ -0,0 +1,23 @@ +--TEST-- +Bug #61418: Segmentation fault using FiltesystemIterator & RegexIterator +--FILE-- +<?php +$fileIterator = new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME); +$regexpIterator = new RegexIterator($fileIterator, '#.*#'); +foreach ($fileIterator as $key => $file) +{ +} +unset($regexpIterator); +unset($fileIterator); + +$dirIterator = new DirectoryIterator(__DIR__); +$regexpIterator2 = new RegexIterator($dirIterator, '#.*#'); +foreach ($dirIterator as $key => $file) +{ +} +unset($regexpIterator2); +unset($dirIterator); +?> +==DONE== +--EXPECT-- +==DONE== Property changes on: php/php-src/branches/PHP_5_3/ext/spl/tests/bug61418.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native Modified: php/php-src/branches/PHP_5_4/ext/spl/spl_directory.c =================================================================== --- php/php-src/branches/PHP_5_4/ext/spl/spl_directory.c 2012-03-18 13:19:50 UTC (rev 324326) +++ php/php-src/branches/PHP_5_4/ext/spl/spl_directory.c 2012-03-18 15:07:20 UTC (rev 324327) @@ -120,6 +120,16 @@ spl_filesystem_file_free_line(intern TSRMLS_CC); break; } + + { + zend_object_iterator *iterator; + iterator = (zend_object_iterator*) + spl_filesystem_object_to_iterator(intern); + if (iterator->data != NULL) { + iterator->data = NULL; + iterator->funcs->dtor(iterator TSRMLS_CC); + } + } efree(object); } /* }}} */ @@ -1638,10 +1648,15 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_dir_it_funcs; - iterator->current = object; + /* initialize iterator if it wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_dir_it_funcs; + /* ->current must be initialized; rewind doesn't set it and valid + * doesn't check whether it's set */ + iterator->current = object; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } @@ -1720,15 +1735,15 @@ static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; - zval *zfree = (zval*)iterator->intern.data; - if (iterator->current) { - zval_ptr_dtor(&iterator->current); + if (iterator->intern.data) { + zval *object = iterator->intern.data; + zval_ptr_dtor(&object); + } else { + if (iterator->current) { + zval_ptr_dtor(&iterator->current); + } } - iterator->intern.data = NULL; /* mark as unused */ - /* free twice as we add ref twice */ - zval_ptr_dtor(&zfree); - zval_ptr_dtor(&zfree); } /* }}} */ @@ -1839,10 +1854,12 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_tree_it_funcs; - iterator->current = NULL; + /* initialize iterator if wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_tree_it_funcs; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } Added: php/php-src/branches/PHP_5_4/ext/spl/tests/bug61418.phpt =================================================================== --- php/php-src/branches/PHP_5_4/ext/spl/tests/bug61418.phpt (rev 0) +++ php/php-src/branches/PHP_5_4/ext/spl/tests/bug61418.phpt 2012-03-18 15:07:20 UTC (rev 324327) @@ -0,0 +1,23 @@ +--TEST-- +Bug #61418: Segmentation fault using FiltesystemIterator & RegexIterator +--FILE-- +<?php +$fileIterator = new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME); +$regexpIterator = new RegexIterator($fileIterator, '#.*#'); +foreach ($fileIterator as $key => $file) +{ +} +unset($regexpIterator); +unset($fileIterator); + +$dirIterator = new DirectoryIterator(__DIR__); +$regexpIterator2 = new RegexIterator($dirIterator, '#.*#'); +foreach ($dirIterator as $key => $file) +{ +} +unset($regexpIterator2); +unset($dirIterator); +?> +==DONE== +--EXPECT-- +==DONE== Property changes on: php/php-src/branches/PHP_5_4/ext/spl/tests/bug61418.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native Modified: php/php-src/trunk/ext/spl/spl_directory.c =================================================================== --- php/php-src/trunk/ext/spl/spl_directory.c 2012-03-18 13:19:50 UTC (rev 324326) +++ php/php-src/trunk/ext/spl/spl_directory.c 2012-03-18 15:07:20 UTC (rev 324327) @@ -120,6 +120,16 @@ spl_filesystem_file_free_line(intern TSRMLS_CC); break; } + + { + zend_object_iterator *iterator; + iterator = (zend_object_iterator*) + spl_filesystem_object_to_iterator(intern); + if (iterator->data != NULL) { + iterator->data = NULL; + iterator->funcs->dtor(iterator TSRMLS_CC); + } + } efree(object); } /* }}} */ @@ -1638,10 +1648,15 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_dir_it_funcs; - iterator->current = object; + /* initialize iterator if it wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_dir_it_funcs; + /* ->current must be initialized; rewind doesn't set it and valid + * doesn't check whether it's set */ + iterator->current = object; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } @@ -1720,15 +1735,15 @@ static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC) { spl_filesystem_iterator *iterator = (spl_filesystem_iterator *)iter; - zval *zfree = (zval*)iterator->intern.data; - if (iterator->current) { - zval_ptr_dtor(&iterator->current); + if (iterator->intern.data) { + zval *object = iterator->intern.data; + zval_ptr_dtor(&object); + } else { + if (iterator->current) { + zval_ptr_dtor(&iterator->current); + } } - iterator->intern.data = NULL; /* mark as unused */ - /* free twice as we add ref twice */ - zval_ptr_dtor(&zfree); - zval_ptr_dtor(&zfree); } /* }}} */ @@ -1839,10 +1854,12 @@ dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); iterator = spl_filesystem_object_to_iterator(dir_object); - Z_SET_REFCOUNT_P(object, Z_REFCOUNT_P(object) + 2); - iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_filesystem_tree_it_funcs; - iterator->current = NULL; + /* initialize iterator if wasn't gotten before */ + if (iterator->intern.data == NULL) { + iterator->intern.data = object; + iterator->intern.funcs = &spl_filesystem_tree_it_funcs; + } + zval_add_ref(&object); return (zend_object_iterator*)iterator; } Added: php/php-src/trunk/ext/spl/tests/bug61418.phpt =================================================================== --- php/php-src/trunk/ext/spl/tests/bug61418.phpt (rev 0) +++ php/php-src/trunk/ext/spl/tests/bug61418.phpt 2012-03-18 15:07:20 UTC (rev 324327) @@ -0,0 +1,23 @@ +--TEST-- +Bug #61418: Segmentation fault using FiltesystemIterator & RegexIterator +--FILE-- +<?php +$fileIterator = new FilesystemIterator(__DIR__, FilesystemIterator::KEY_AS_FILENAME); +$regexpIterator = new RegexIterator($fileIterator, '#.*#'); +foreach ($fileIterator as $key => $file) +{ +} +unset($regexpIterator); +unset($fileIterator); + +$dirIterator = new DirectoryIterator(__DIR__); +$regexpIterator2 = new RegexIterator($dirIterator, '#.*#'); +foreach ($dirIterator as $key => $file) +{ +} +unset($regexpIterator2); +unset($dirIterator); +?> +==DONE== +--EXPECT-- +==DONE== Property changes on: php/php-src/trunk/ext/spl/tests/bug61418.phpt ___________________________________________________________________ Added: svn:keywords + Id Rev Revision Added: svn:eol-style + native
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php