]> granicus.if.org Git - php/commitdiff
Fixed bug #60138 (GC crash with referenced array in RecursiveArrayIterator)
authorDmitry Stogov <dmitry@php.net>
Fri, 18 Nov 2011 12:43:53 +0000 (12:43 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 18 Nov 2011 12:43:53 +0000 (12:43 +0000)
NEWS
Zend/tests/bug60138.phpt [new file with mode: 0644]
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index 3318b784e10577eec44abcbd0e81faa91637b86b..577d2d59fee5c155c68423209a3e50a4e7579554 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP                                                                        NEWS
 ?? ??? 2011, PHP 5.3.9
 
 - Core:
+  . Fixed bug #60138 (GC crash with referenced array in RecursiveArrayIterator)
+    (Dmitry).
   . Fixed bug #60099 (__halt_compiler() works in braced namespaces). (Felipe)
   . Fixed bug #55874 (GCC does not provide __sync_fetch_and_add on some archs).
     (klightspeed at netspace dot net dot au)
diff --git a/Zend/tests/bug60138.phpt b/Zend/tests/bug60138.phpt
new file mode 100644 (file)
index 0000000..3bf1fba
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #60138 (GC crash with referenced array in RecursiveArrayIterator)
+--FILE--
+<?php
+$tree = array(array("f"));
+$category =& $tree[0];
+
+$iterator = new RecursiveIteratorIterator(
+    new RecursiveArrayIterator($tree),
+    RecursiveIteratorIterator::SELF_FIRST
+);
+foreach($iterator as $file);
+echo "ok\n";
+?>
+--EXPECT--
+ok
index 8a3ec3b5d0a9d1b37cf3c73245a1e6ea11ba5ce8..d5a8d32f23dcde29b07111d37dcf299c877375d6 100644 (file)
@@ -865,10 +865,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                        && (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 
                        && !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
                        && PZVAL_IS_REF(*fci->params[i])) {
-                       SEPARATE_ZVAL(fci->params[i]);
-               }
-
-               if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
+                       ALLOC_ZVAL(param);
+                       *param = **(fci->params[i]);
+                       INIT_PZVAL(param);
+                       zval_copy_ctor(param);
+               } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
                        && !PZVAL_IS_REF(*fci->params[i])) {
 
                        if (Z_REFCOUNT_PP(fci->params[i]) > 1) {