php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71241 array_replace_recursive sometimes mutates its parameters
Submitted: 2015-12-30 00:03 UTC Modified: 2016-09-01 16:12 UTC
Votes:2
Avg. Score:4.0 ± 1.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: as@php.net Assigned:
Status: Closed Package: Variables related
PHP Version: 7.0.1 OS:
Private report: No CVE-ID:
 [2015-12-30 00:03 UTC] as@php.net
Description:
------------
array_replace_recursive can sometimes mutate its params if references are nested within. This appears to be new behavior in PHP7. It also affects PHPunit.

Test script and diff: https://3v4l.org/0sdbm

Patch attached.


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

$one = [1];
$two = [42];

$arr1 = ['k' => &$one];
$arr2 = ['k' => &$two];
var_dump(current($one), current($two));
array_replace_recursive($arr1, $arr2);
var_dump(current($one), current($two));


Expected result:
----------------
int(1)
int(42)
int(1)
int(42)


Actual result:
--------------
int(1)
int(42)
int(42)
int(42)


Patches

fix_array_replace_recursive_ref_mut (last revision 2015-12-30 00:03 UTC) by as@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-12-30 00:03 UTC] as@php.net
The following patch has been added/updated:

Patch Name: fix_array_replace_recursive_ref_mut
Revision:   1451433803
URL:        https://bugs.php.net/patch-display.php?bug=71241&patch=fix_array_replace_recursive_ref_mut&revision=1451433803
 [2015-12-30 03:00 UTC] laruence@php.net
the new behavior is more correct, $arr1['k'] is a reference:

it behavior consistently with :

<?php
$one = [1];
$arr1 = ['k' => &$one];
$arr1['k'] = 2;

var_dump($one); //output 2

so, I think no bug here. 

thanks
 [2015-12-30 03:01 UTC] laruence@php.net
-Status: Open +Status: Not a bug
 [2015-12-30 03:01 UTC] laruence@php.net
close as not a bug.
 [2016-01-11 18:17 UTC] as@php.net
Thanks for checking it out laruence. In that case, is `array_merge_recursive` buggy? It exhibits the old behavior: https://3v4l.org/NSa9S

There is also a related oddity illustrated here https://3v4l.org/sYutE which again only seems to affect `array_replace_recursive`.

I can open separate bugs if that's easier to track, but I think it's all the same root issue.
 [2016-01-26 22:46 UTC] rasmus@php.net
-Status: Not a bug +Status: Open
 [2016-01-26 22:46 UTC] rasmus@php.net
Re-opened. This does seem like a real bug in array_merge_recursive()
 [2016-09-01 16:12 UTC] nikic@php.net
@laruence: But isn't array_replace_recursive() supposed to return a new array while leaving the original arguments alone?

A more accurate version of your example would be

<?php
$one = [1];
$arr1 = ['k' => &$one];
$result = [];
$result['k'] = $arr1['k'];
$result['k'] = 2;

In which case $one would remain unchanged.

Imho this is a bug in the PHP 7 implementation and it should instead return the PHP 5 result.
 [2016-10-20 11:27 UTC] nikic@php.net
Automatic comment on behalf of as
Revision: http://git.php.net/?p=php-src.git;a=commit;h=55d17662cb61bc29f443276b0cd50b3a62f91acc
Log: Fix bug #71241: array_replace_recursive mutates ref params
 [2016-10-20 11:27 UTC] nikic@php.net
-Status: Open +Status: Closed
 [2016-10-25 15:21 UTC] krakjoe@php.net
Automatic comment on behalf of as
Revision: http://git.php.net/?p=php-src.git;a=commit;h=55d17662cb61bc29f443276b0cd50b3a62f91acc
Log: Fix bug #71241: array_replace_recursive mutates ref params
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Jul 23 14:01:36 2017 UTC