]> granicus.if.org Git - php/commitdiff
- Fixed bug #54358 (Closure, use and reference)
authorDmitry Stogov <dmitry@php.net>
Fri, 8 Apr 2011 10:02:07 +0000 (10:02 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 8 Apr 2011 10:02:07 +0000 (10:02 +0000)
- Fixed bug #54039 (use() of static variables in lambda functions can break staticness)

Zend/tests/bug54039.phpt [new file with mode: 0644]
Zend/tests/bug54358.phpt [new file with mode: 0644]
Zend/zend_variables.c

diff --git a/Zend/tests/bug54039.phpt b/Zend/tests/bug54039.phpt
new file mode 100644 (file)
index 0000000..ccdfe94
--- /dev/null
@@ -0,0 +1,58 @@
+--TEST--
+Bug #54039 (use() of static variables in lambda functions can break staticness)
+--FILE--
+<?php
+function test_1() {
+       static $v = 0;
+       ++$v;
+       echo "Outer function increments \$v to $v\n";
+       $f = function() use($v) {
+               echo "Inner function reckons \$v is $v\n";
+       };
+       return $f;
+}
+
+$f = test_1(); $f();
+$f = test_1(); $f();
+
+function test_2() {
+       static $v = 0;
+       $f = function() use($v) {
+               echo "Inner function reckons \$v is $v\n";
+       };
+       ++$v;
+       echo "Outer function increments \$v to $v\n";
+       return $f;
+}
+
+$f = test_2(); $f();
+$f = test_2(); $f();
+
+function test_3() {
+       static $v = "";
+       $v .= 'b';
+       echo "Outer function catenates 'b' onto \$v to give $v\n";
+       $f = function() use($v) {
+               echo "Inner function reckons \$v is $v\n";
+       };
+       $v .= 'a';
+       echo "Outer function catenates 'a' onto \$v to give $v\n";
+       return $f;
+}
+$f = test_3(); $f();
+$f = test_3(); $f();
+--EXPECT--
+Outer function increments $v to 1
+Inner function reckons $v is 1
+Outer function increments $v to 2
+Inner function reckons $v is 2
+Outer function increments $v to 1
+Inner function reckons $v is 0
+Outer function increments $v to 2
+Inner function reckons $v is 1
+Outer function catenates 'b' onto $v to give b
+Outer function catenates 'a' onto $v to give ba
+Inner function reckons $v is b
+Outer function catenates 'b' onto $v to give bab
+Outer function catenates 'a' onto $v to give baba
+Inner function reckons $v is bab
diff --git a/Zend/tests/bug54358.phpt b/Zend/tests/bug54358.phpt
new file mode 100644 (file)
index 0000000..faeeeac
--- /dev/null
@@ -0,0 +1,39 @@
+--TEST--
+Bug #54358 (Closure, use and reference)
+--FILE--
+<?php
+class asserter {
+       public function call($function) {
+       }
+}
+
+$asserter = new asserter();
+
+$closure = function() use ($asserter, &$function) {
+        $asserter->call($function = 'md5');
+};
+
+$closure();
+
+var_dump($function);
+
+$closure = function() use ($asserter, $function) {
+        $asserter->call($function);
+};
+
+$closure();
+
+var_dump($function);
+
+$closure = function() use ($asserter, $function) {
+        $asserter->call($function);
+};
+
+$closure();
+
+var_dump($function);
+?>
+--EXPECT--
+string(3) "md5"
+string(3) "md5"
+string(3) "md5"
index 77d42bc5c4e5cf396d4e1b08b58caeb9e817496d..5e500ea635fabfe7af79325f3591971432dfc237 100644 (file)
@@ -216,6 +216,7 @@ ZEND_API int zval_copy_static_var(zval **p TSRMLS_DC, int num_args, va_list args
                        } else if (Z_ISREF_PP(p)) {
                                ALLOC_INIT_ZVAL(tmp);
                                ZVAL_COPY_VALUE(tmp, *p);
+                               zval_copy_ctor(tmp);
                                Z_SET_REFCOUNT_P(tmp, 0);
                                Z_UNSET_ISREF_P(tmp);
                        } else {