Bug #73753 [Com]: unserialized array pointer not advancing
| From: | dave at mudsite dot com | Date: | Tue, 20 Dec 2016 23:19:46 +0000 |
| Subject: | Bug #73753 [Com]: unserialized array pointer not advancing | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-206167@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73753&edit=1
ID: 73753
Comment by: dave at mudsite dot com
Reported by: devosc at gmail dot com
Summary: unserialized array pointer not advancing
Status: Verified
Type: Bug
Package: Scripting Engine problem
PHP Version: 7.1.0
Block user comment: N
Private report: N
New Comment:
It looks like this problem has to do with unpacked arrays. You can change the $queue to:
$queue = [1 = 'foo', 'b' => 'bar', 'baz'];
without the serialize/unserialize and demonstrate the same problem.
I'm not overly versed with the packed/unpacked array but I believe this issue was introduced
with b250f467035d3307853b6cf03be3b6b898bcaa80 (included in PHP 7.0). The problem being with the
zend_array_dup(), specifically how it handles the else case (non-packed array). It attempts to
zend_array_dup_elements(), which loops trying to dupe each element. If it can, it keeps going.
Only when it can't, when due to inderect&undef, or when has holes&undef, would it fall
into a case where it'd check if the idx equals the source arrays internal pointer.
I believe the fix to this would be to change the zend_array_dup_elements, to also check the
source's internal index to the current idx, and if they match set the targets. It does fix
this bugs problem, but would want to ensure that it's valid for other cases I'm not overly
familiar with.
Previous Comments:
------------------------------------------------------------------------
[2016-12-16 14:47:17] cmb@php.net
Confirmed: <https://3v4l.org/QmfJM#v563>.
------------------------------------------------------------------------
[2016-12-15 19:14:33] devosc at gmail dot com
Description:
------------
Internal pointer of unserialized array does not advance correctly.
Test script:
---------------
<?php
function iterate($current, $queue, $result = null)
{
if (!$current) {
return $result;
}
return iterate(step($queue), $queue, $current);
}
function step(&$queue)
{
return next($queue);
}
function start($queue)
{
return current($queue);
}
function traverse($queue)
{
return iterate(start($queue), $queue);
}
$queue = ['foo', 'bar', 'baz'];
$queue = unserialize(serialize($queue));
echo traverse($queue); //baz
Expected result:
----------------
It should output 'baz'.
Actual result:
--------------
Recursion error. The internal pointer is stuck on the second item and does not move forward. It
works in 5.6 and when $queue is a reference in the signature of the iterate function. Seems
inconsistent.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73753&edit=1