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

Reply via email to