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: 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: as@php.net
New email:
PHP Version: OS:

 

 [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)

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC