diff --git a/Zend/tests/gc_046.phpt b/Zend/tests/gc_046.phpt new file mode 100644 index 00000000000..74481fb76a7 --- /dev/null +++ b/Zend/tests/gc_046.phpt @@ -0,0 +1,23 @@ +--TEST-- +GC 046: Leak in User Iterator +--INI-- +zend.enable_gc=1 +--FILE-- +iterator = new ArrayIterator($this); + } + function filter() { + $this->iterator = new CallbackFilterIterator($this->iterator, fn() => true); + $this->iterator->rewind(); + } +} + +$action=new Action; +$action->filter(); +$action->filter(); +?> +DONE +--EXPECT-- +DONE diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index ec14b1a99a0..d05310b737b 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -184,8 +184,15 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter) ZEND_API HashTable *zend_user_it_get_gc(zend_object_iterator *_iter, zval **table, int *n) { zend_user_iterator *iter = (zend_user_iterator*)_iter; - *table = &iter->it.data; - *n = 1; + if (Z_ISUNDEF(iter->value)) { + *table = &iter->it.data; + *n = 1; + } else { + zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); + zend_get_gc_buffer_add_zval(gc_buffer, &iter->it.data); + zend_get_gc_buffer_add_zval(gc_buffer, &iter->value); + zend_get_gc_buffer_use(gc_buffer, table, n); + } return NULL; }