php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52940 call_user_func_array still allows call-time pass-by-reference
Submitted: 2010-09-28 04:53 UTC Modified: 2010-10-01 13:54 UTC
From: cataphract@php.net Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: trunk-SVN-2010-09-28 (SVN) OS: Windows 7 x64; Debian Lenny x64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: cataphract@php.net
New email:
PHP Version: OS:

 

 [2010-09-28 04:53 UTC] cataphract@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

Patches

no_call_time_pass_by_ref_via_ZCF (last revision 2010-09-28 04:49 UTC by cataphract@php.net)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-28 06:49 UTC] cataphract@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 06:51 UTC] cataphract@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 07:11 UTC] cataphract@php.net
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);
 [2010-09-28 11:44 UTC] pajoye@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: dmitry
 [2010-09-28 11:44 UTC] pajoye@php.net
hi Dmitry,

Can you look at this pls?
 [2010-09-29 23:13 UTC] cataphract@php.net
Fixing this would also fix bug #51986.
 [2010-10-01 13:53 UTC] dmitry@php.net
Automatic comment from SVN on behalf of dmitry
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=303919
Log: Fixed bug #52940 (call_user_func_array still allows call-time pass-by-reference). (cataphract@php.net)
 [2010-10-01 13:54 UTC] dmitry@php.net
-Status: Assigned +Status: Closed
 [2010-10-01 13:54 UTC] dmitry@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Apr 01 15:01:31 2025 UTC