1
0
mirror of https://github.com/php/php-src.git synced 2026-04-27 18:23:26 +02:00
A generator iterator can be created from different zvals - use
the object handle to manage references instead.
This commit is contained in:
Nikita Popov
2015-03-11 18:08:03 +01:00
parent 6b643f0741
commit a9d73f0646
5 changed files with 53 additions and 7 deletions
+2
View File
@@ -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
+24
View File
@@ -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)
+20
View File
@@ -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)
}
+4 -4
View File
@@ -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;
}
+3 -3
View File
@@ -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 {