php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76864 Returned reference is removed if executing inside a namespace
Submitted: 2018-09-11 19:24 UTC Modified: 2020-03-04 10:39 UTC
From: tshumbeo at mailhouse dot biz Assigned: nikic (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.2.9 OS: Linux and Windows
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: tshumbeo at mailhouse dot biz
New email:
PHP Version: OS:

 

 [2018-09-11 19:24 UTC] tshumbeo at mailhouse dot biz
Description:
------------
Tested on PHP 5.6.37 and 7.2.9, Windows and Linux, various configurations.

See the test script. When (1) is present (executing inside any namespace except global) and (2) does *not* accept $o by reference, the returned array is missing the reference that was created. As a result, subsequent call to sort() fails with this warning:

  Parameter 1 to sort() expected to be a reference, value given

This is mind-boggling because removing the namespace (1) leaves the reference alone. Alternatively, making f() accept $o by reference (2) also removes the problem:

  namespace X;
  function f(array &$o) 
  ...

(1) | (2) | Result
----|-----|-------
 X  | &   | no bug
    | &   | no bug
    |     | no bug
 X  |     | bug!

Yet more, if f()'s result is directly passed into call_user_func_array() bypassing a temporary variable, the reference seems to stick and the problem doesn't appear.

Test script:
---------------
<?php 

// (1) 
namespace X;

// (2) 
function f(array $o) {
  return [&$o['v']];
}

$v = ['z', 'a'];
$a = ['v' => $v];

$args = f($a);
call_user_func_array('sort', $args);
// Additionally, if the above 2 lines are replaced by the following
// line, the bug never appears.
//call_user_func_array('sort', f($a));

Expected result:
----------------
Members returned by reference must be kept regardless of the namespace, $o-by-reference or use of intermediate variables.

Actual result:
--------------
The reference is lost when executing under a non-global namespace, not accepting $o by reference and using an intermediate variable.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-09-14 13:07 UTC] sjon at hortensius dot net
This is fixed in 7.3, see https://3v4l.org/QE9Vf

since most commits don't compile I am unable to bisect this
 [2020-03-04 10:39 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2020-03-04 10:39 UTC] nikic@php.net
Closing per above comment.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Wed Jul 16 03:01:33 2025 UTC