summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug60139.phpt30
-rw-r--r--Zend/zend_closures.c13
3 files changed, 45 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index e2ac9dcdb8..9e9334542a 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP NEWS
?? ??? 2011, PHP 5.3.9
- Core:
+ . Fixed bug #60139 (Anonymous functions create cycles not detected by the
+ GC). (Dmitry)
. Fixed bug #60120 (proc_open's streams may hang with stdin/out/err when
the data exceeds or is equal to 2048 bytes). (Pierre, Pascal Borreli)
. Fixed bug #60019 (Function time_nanosleep() is undefined on OS X). (Ilia)
diff --git a/Zend/tests/bug60139.phpt b/Zend/tests/bug60139.phpt
new file mode 100644
index 0000000000..e429fe2b03
--- /dev/null
+++ b/Zend/tests/bug60139.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #60139 (Anonymous functions create cycles not detected by the GC)
+--FILE--
+<?php
+class Foo {
+ public $x;
+
+ public function __construct() {
+ $this->x = function() {};
+ }
+}
+
+class Bar {
+ public $x;
+
+ public function __construct() {
+ $self = $this;
+ $this->x = function() use ($self) {};
+ }
+}
+
+gc_collect_cycles();
+new Foo;
+var_dump(gc_collect_cycles());
+new Bar;
+var_dump(gc_collect_cycles());
+?>
+--EXPECT--
+int(0)
+int(2)
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index faa3b7705c..80a8eb8900 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -280,6 +280,18 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
}
/* }}} */
+static HashTable *zend_closure_get_properties(zval *obj TSRMLS_DC) /* {{{ */
+{
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+
+ if (GC_G(gc_active)) {
+ return (closure->func.type == ZEND_USER_FUNCTION) ? closure->func.op_array.static_variables : NULL;
+ }
+
+ return closure->std.properties;
+}
+/* }}} */
+
/* {{{ proto Closure::__construct()
Private constructor preventing instantiation */
ZEND_METHOD(Closure, __construct)
@@ -316,6 +328,7 @@ void zend_register_closure_ce(TSRMLS_D) /* {{{ */
closure_handlers.clone_obj = NULL;
closure_handlers.get_debug_info = zend_closure_get_debug_info;
closure_handlers.get_closure = zend_closure_get_closure;
+ closure_handlers.get_properties = zend_closure_get_properties;
}
/* }}} */