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

Reply via email to