Edit report at http://bugs.php.net/bug.php?id=52940&edit=1
ID: 52940 Updated by: cataphr...@php.net Reported by: cataphr...@php.net Summary: call_user_func_array still allows call-time pass-by-reference Status: Open Type: Bug Package: Scripting Engine problem Operating System: Windows 7 x64; Debian Lenny x64 PHP Version: trunk-SVN-2010-09-28 (SVN) Block user comment: N New Comment: I've left the exception that was introduced for bug #50394, though I think it should be removed for trunk. It makes no sense to disallow this: <?php class A { function __call($name, $args) { var_dump($args); } } $a = new A; $b = 6; $a->foobar(&$a); yet allow this: <?php class A { function __call($name, $args) { var_dump($args); } } $a = new A; $b = 6; call_user_func_array(array($a, 'foobar'), array(&$b)); The problem described in bug #50394 could easily be worked around by, instead of passing by reference to __call, give the argument in an array instead: <?php function foo( &$x ) { $x++; } class Proxy { function __call( $name, $args ) { call_user_func_array( 'foo', $args[0] ); } } $arg = 1; $args = array( &$arg ); $proxy = new Proxy; call_user_func_array( array( $proxy, 'bar' ), array($args) ); var_dump($arg); Previous Comments: ------------------------------------------------------------------------ [2010-09-28 06:51:01] cataphr...@php.net I ended up implemented a better strategy than separate+clear flag, as that broke a few tests that expected the fci.params's zvals not to have the reference flag changed. This patch breaks only two tests that explicitly tested for the previous behavior. ------------------------------------------------------------------------ [2010-09-28 06:49:27] cataphr...@php.net The following patch has been added/updated: Patch Name: no_call_time_pass_by_ref_via_ZCF Revision: 1285649367 URL: http://bugs.php.net/patch-display.php?bug=52940&patch=no_call_time_pass_by_ref_via_ZCF&revision=1285649367 ------------------------------------------------------------------------ [2010-09-28 04:53:54] cataphr...@php.net Description: ------------ zend_call_function does not properly convert references into non-references, hence allowing passing by reference arguments to functions that expect values. See also bug #43484. This is harder to do with internal function because there's currently a variable separation for those. However, it's still not impossible, because if I'm not mistaken there are ways to make the engine give you a variable with is_ref = 1, refcount <= 1. I propose making the behavior for internal functions consistent with that of user functions by separating the variable all time if it's a reference and the parameter is to be sent by value; for cases where is_ref = 1, refcount <= 1, the reference flag should be cleared. Test script: --------------- <?php $a = 1; function test($a) { $a++; } test($a); echo $a; call_user_func_array('test', array(&$a)); echo $a; Expected result: ---------------- 11 Actual result: -------------- 12 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/bug.php?id=52940&edit=1