summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcus Boerger <helly@php.net>2009-01-03 18:22:20 +0000
committerMarcus Boerger <helly@php.net>2009-01-03 18:22:20 +0000
commitb7bb8034b56eddc257276b39b6645b80b0160e2c (patch)
treefa7d80be56ebe0a70ab7c2affd8c9dbf3b5c63d2
parent0e131653c17b22a1609387d758ffecaf8e8f64bc (diff)
downloadphp-git-b7bb8034b56eddc257276b39b6645b80b0160e2c.tar.gz
- MFH Fix refcounting
-rwxr-xr-xZend/tests/closure_035.phpt44
-rw-r--r--Zend/zend_closures.c6
2 files changed, 50 insertions, 0 deletions
diff --git a/Zend/tests/closure_035.phpt b/Zend/tests/closure_035.phpt
new file mode 100755
index 0000000000..7fff623957
--- /dev/null
+++ b/Zend/tests/closure_035.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Closure 035: Rebinding closure $this on property access
+--FILE--
+<?php
+
+$instance = 0;
+
+class Test {
+ function __construct() {
+ global $instance;
+ $this->instance = ++$instance;
+ }
+}
+
+$o = new Test;
+$o->func = function () {
+ var_dump($this);
+};
+$func = $o->func;
+$func();
+
+var_dump($instance);
+?>
+===DONE===
+--EXPECTF--
+object(Test)#%d (2) {
+ ["instance"]=>
+ int(1)
+ ["func"]=>
+ object(Closure)#%d (1) {
+ ["this"]=>
+ object(Test)#%d (2) {
+ ["instance"]=>
+ int(1)
+ ["func"]=>
+ object(Closure)#2 (1) {
+ ["this"]=>
+ *RECURSION*
+ }
+ }
+ }
+}
+int(1)
+===DONE=== \ No newline at end of file
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index 1f65e11668..f646550cbd 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -124,7 +124,13 @@ ZEND_API zval* zend_closure_copy(zval *closure_obj, zval *this_ptr TSRMLS_DC) /*
zval_copy_ctor(closure_obj);
closure = (zend_closure *)zend_object_store_get_object(closure_obj TSRMLS_CC);
+ if (closure->this_ptr) {
+ zval_ptr_dtor(&closure->this_ptr);
+ }
closure->this_ptr = this_ptr;
+ if (this_ptr) {
+ Z_ADDREF_P(this_ptr);
+ }
return closure_obj;
}
/* }}} */