]> 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)

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

diff --git a/NEWS b/NEWS
index 801611684f2a57a47c1d5e6cf7eb8387d35b59cd..36831c81d8a269cc2cf3f4b63db511281ca14cd6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ PHP                                                                        NEWS
     (Tony, Dmitry)
   . Fixed bug #54372 (Crash accessing global object itself returned from its
     __get() handle). (Dmitry)
+  . Fixed bug #54358 (Closure, use and reference). (Dmitry)
+  . Fixed bug #54039 (use() of static variables in lambda functions can break
+     staticness). (Dmitry)
   . Fixed bug #54262 (Crash when assigning value to a dimension in a non-array).
     (Dmitry)
 
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 d460416e6cea018b1838d3caa563c0ff4d19389f..fa26f6efaa425c0a9008b55ead4f28104e88f831 100644 (file)
@@ -347,6 +347,7 @@ static 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);
                                *tmp = **p;
+                               zval_copy_ctor(tmp);
                                Z_SET_REFCOUNT_P(tmp, 0);
                                Z_UNSET_ISREF_P(tmp);
                        } else {