php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch no_call_time_pass_by_ref_via_ZCF for Scripting Engine problem Bug #52940

Patch version 2010-09-28 04:49 UTC

Return to Bug #52940 | Download this patch
Patch Revisions:

Developer: cataphract@php.net

Index: ext/standard/tests/array/array_map_variation19.phpt
===================================================================
--- ext/standard/tests/array/array_map_variation19.phpt	(revision 303758)
+++ ext/standard/tests/array/array_map_variation19.phpt	(working copy)
@@ -9,6 +9,7 @@
 
 /*
  * Test array_map() with a pass-by-value callback forced to behave as a pass-by-reference function.
+ * This is no longer allowed; the callback retains pass-by-value semantics
  */
 
 $arr1 = array('original.0', 'original.1');
@@ -34,7 +35,7 @@
 }
 array(2) {
   [0]=>
-  &string(7) "changed"
+  &string(10) "original.0"
   [1]=>
   string(10) "original.1"
 }
\ No newline at end of file
Index: ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt
===================================================================
--- ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt	(revision 303758)
+++ ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt	(working copy)
@@ -1,5 +1,5 @@
 --TEST--
-call_user_func_array() passes by reference if the array element is referenced, regardless of function signature.
+call_user_func_array() passes by reference if the array element is referenced, only if allowed by the function signature.
 --FILE--
 <?php
 
@@ -50,7 +50,7 @@
 ------ Calling by_val() with referenced argument ------
 array(1) {
   [0]=>
-  &string(7) "changed"
+  &string(8) "original"
 }
 ------ Calling by_ref() with referenced argument ------
 array(1) {
Index: Zend/zend_execute_API.c
===================================================================
--- Zend/zend_execute_API.c	(revision 303758)
+++ Zend/zend_execute_API.c	(working copy)
@@ -850,13 +850,6 @@
 	for (i=0; i<fci->param_count; i++) {
 		zval *param;
 
-		if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION 
-			&& (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)
 			&& !PZVAL_IS_REF(*fci->params[i])) {
 
@@ -888,6 +881,16 @@
 			Z_ADDREF_PP(fci->params[i]);
 			Z_SET_ISREF_PP(fci->params[i]);
 			param = *fci->params[i];
+		} else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)
+			&& PZVAL_IS_REF(*fci->params[i])
+			&& (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0) {
+			/* still allows deviant behavior for __call */
+			zval *new_zval;
+			ALLOC_ZVAL(new_zval);
+			*new_zval = **fci->params[i];
+			INIT_PZVAL(new_zval);
+			zval_copy_ctor(new_zval);
+			param = new_zval;
 		} else if (*fci->params[i] != &EG(uninitialized_zval)) {
 			Z_ADDREF_PP(fci->params[i]);
 			param = *fci->params[i];
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 27 15:01:29 2024 UTC