Bug #66107 [Asn]: func_get_args change breaks by-reference in ReflectionClass::newInstanceArgs

From: Date: Mon, 25 Nov 2013 12:40:18 +0000
Subject: Bug #66107 [Asn]: func_get_args change breaks by-reference in ReflectionClass::newInstanceArgs
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-182916@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66107&edit=1

 ID:                 66107
 Updated by:         dmitry@php.net
 Reported by:        sjon at hortensius dot net
 Summary:            func_get_args change breaks by-reference in
                     ReflectionClass::newInstanceArgs
 Status:             Assigned
 Type:               Bug
 Package:            Arrays related
 Operating System:   archlinux
 PHP Version:        5.5.6
 Assigned To:        dmitry
 Block user comment: N
 Private report:     N

 New Comment:

Actually, this code worked not on purpose but because of luck.
Previously, func_get_args() copied each argument making refcount == 1 and it allowed to pass it by
reference.

The following code demonstrates the real reason of the bug. The first call to call_user_func_array()
works but the second doesn't.

<?php
function foo(&$e) {
	var_dump($e);
}
call_user_func_array("foo", array(2));
$a = array(2);
call_user_func_array("foo", $a);
?>

The problem may be related to zend_fcall_info.no_separation handling.


Previous Comments:
------------------------------------------------------------------------
[2013-11-18 09:32:43] sjon at hortensius dot net

Since $e is an object it is already passed by reference; so the error is rather strange. The code
seems to check for an explicit &$e by-reference instead of an implicit variable=object=reference

------------------------------------------------------------------------
[2013-11-17 15:24:21] sjon at hortensius dot net

Description:
------------
The changelog states:

> Improved performance of array_merge() and func_get_args() by eliminating useless copying.

I think I found a bug related to this change. If it's not fixed it should at least be
documented.

Test script:
---------------
From http://3v4l.org/U40T0

<?php
class f
{
    function f(&$e){}
}

function getNew()
{
    $a = func_get_args();
    $c = array_shift($a);

    $r = new ReflectionClass($c);
    return $r->newInstanceArgs($a);
}

$e = new stdClass;

var_dump(getNew('f', $e));

Expected result:
----------------
object(f)#3 (0) {
}

Actual result:
--------------
Warning: Parameter 1 to f::f() expected to be a reference, value given in /in//in/U40T0 on line 14

Warning: ReflectionClass::newInstanceArgs(): Invocation of f's constructor failed in
/in//in/U40T0 on line 14
NULL


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=66107&edit=1


Thread (12 messages)

« previous php.bugs (#182916) next »