Bug #73753 [Ver->Csd]: unserialized array pointer not advancing

From: Date: Wed, 21 Dec 2016 20:20:08 +0000
Subject: Bug #73753 [Ver->Csd]: unserialized array pointer not advancing
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206180@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 Updated by: nikic@php.net Reported by: devosc at gmail dot com Summary: unserialized array pointer not advancing -Status: Verified +Status: Closed Type: Bug Package: Scripting Engine problem PHP Version: 7.1.0 Block user comment: N Private report: N New Comment: Automatic comment on behalf of dave@mudsite.com Revision: http://git.php.net/?p=php-src.git;a=commit;h=5733fd1cafe8d0e2306626c525ad081b7ee30d96 Log: Fix #73753 - Unpacked Arrays and Duplication Previous Comments: ------------------------------------------------------------------------ [2016-12-20 23:19:45] dave at mudsite dot com 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. ------------------------------------------------------------------------ [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

« previous php.bugs (#206180) next »