com php-src: Fixed bug #69221: NEWS Zend/tests/bug69221.phpt Zend/tests/bug69221_2.phpt Zend/zend_genera tors.c Zend/zend_generators.h
| From: | Nikita Popov | Date: | Fri, 13 Mar 2015 15:23:53 +0000 |
| Subject: | com php-src: Fixed bug #69221: NEWS Zend/tests/bug69221.phpt Zend/tests/bug69221_2.phpt Zend/zend_genera tors.c Zend/zend_generators.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-85495@lists.php.net to get a copy of this message | ||
Commit: a9d73f0646ca95134f5f2ada0899a7616c1ea705
Author: Nikita Popov <nikic@php.net> Wed, 11 Mar 2015 18:08:03 +0100
Parents: 6b643f0741e59fb2473e23c0ead6715b661845b1
Branches: PHP-5.5 PHP-5.6 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=a9d73f0646ca95134f5f2ada0899a7616c1ea705
Log:
Fixed bug #69221
A generator iterator can be created from different zvals - use
the object handle to manage references instead.
Bugs:
https://bugs.php.net/69221
Changed paths:
M NEWS
A Zend/tests/bug69221.phpt
A Zend/tests/bug69221_2.phpt
M Zend/zend_generators.c
M Zend/zend_generators.h
Diff:
diff --git a/NEWS b/NEWS
index 3a431bf..39e404f 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ PHP NEWS
. Fixed bug #68917 (parse_url fails on some partial urls). (Wei Dai)
. Fixed bug #69212 (Leaking VIA_HANDLER func when exception thrown in
__call/... arg passing). (Nikita)
+ . Fixed bug #69221 (Segmentation fault when using a generator in combination
+ with an Iterator). (Nikita)
- Filter:
. Fixed bug #69202: (FILTER_FLAG_STRIP_BACKTICK ignored unless other
diff --git a/Zend/tests/bug69221.phpt b/Zend/tests/bug69221.phpt
new file mode 100644
index 0000000..9eb5afc
--- /dev/null
+++ b/Zend/tests/bug69221.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #69221: Segmentation fault when using a generator in combination with an Iterator
+--FILE--
+<?php
+
+function gen() {
+ yield 1;
+};
+
+$gen1 = gen();
+$gen2 = (object) $gen1;
+
+foreach ($gen1 as $v1) {
+ foreach ($gen2 as $v2) {
+ break 2;
+ }
+}
+
+unset($gen1);
+foreach ($gen2 as $v) { var_dump($v); }
+
+?>
+--EXPECTF--
+int(1)
diff --git a/Zend/tests/bug69221_2.phpt b/Zend/tests/bug69221_2.phpt
new file mode 100644
index 0000000..f3805b8
--- /dev/null
+++ b/Zend/tests/bug69221_2.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #69221: Segmentation fault when using a generator in combination with an Iterator (2)
+--FILE--
+<?php
+
+$gen = function() {
+ yield 1;
+};
+
+$iter = new IteratorIterator($gen());
+$ngen = $iter->getInnerIterator();
+
+var_dump(iterator_to_array($ngen, false));
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ int(1)
+}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index c96d1e9..b457f56 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -605,9 +605,9 @@ ZEND_METHOD(Generator, __wakeup)
static void zend_generator_iterator_dtor(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
{
- zval *object = ((zend_generator_iterator *) iterator)->object;
+ zend_generator_iterator *iter = (zend_generator_iterator *) iterator;
- zval_ptr_dtor(&object);
+ zend_objects_store_del_ref_by_handle(iter->handle TSRMLS_CC);
}
/* }}} */
@@ -699,8 +699,8 @@ zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *ob
/* We have to keep a reference to the generator object zval around,
* otherwise the generator may be destroyed during iteration. */
- Z_ADDREF_P(object);
- iterator->object = object;
+ iterator->handle = Z_OBJ_HANDLE_P(object);
+ zend_objects_store_add_ref_by_handle(iterator->handle TSRMLS_CC);
return (zend_object_iterator *) iterator;
}
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index d460c90..061ea51 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -28,9 +28,9 @@ extern ZEND_API zend_class_entry *zend_ce_generator;
typedef struct _zend_generator_iterator {
zend_object_iterator intern;
- /* The generator object zval has to be stored, because the iterator is
- * holding a ref to it, which has to be dtored. */
- zval *object;
+ /* The generator object handle has to be stored, because the
+ * iterator is holding a ref to it, which has to be dtored. */
+ zend_object_handle handle;
} zend_generator_iterator;
typedef struct _zend_generator {