mirror of
https://github.com/php/php-src.git
synced 2026-04-27 18:23:26 +02:00
Fixed bug #69221
A generator iterator can be created from different zvals - use the object handle to manage references instead.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user