mirror of
https://github.com/php/php-src.git
synced 2026-03-24 16:22:37 +01:00
Previously, if an object had RC1 it would never be recorded in php_serialize_data.ht because it was assumed that it could not be encountered again. This assumption is incorrect though as the object itself may be saved inside an array with RCn. This results in a new instance of the object, instead of a second reference to the same object. This is solved by tracking these objects in php_serialize_data.ht. To retain performance, track if the current object resides in a potentially nested RCn array. If not, and if the object is RC1 itself it may be omitted from php_serialize_data.ht. Additionally, we may treat the array root itself as RC1 because it may not appear in the object graph again without recursion. Recursive arrays are still somewhat broken even with this change, as the tracking of the array only happens when the reference is encountered, thus resulting in a -> a' -> a' for a self recursive array a -> a. Recursive arrays have limited support in serialize anyway, so we ignore this case for now. Co-authored-by: Dmitry Stogov <dmitry@zend.com> Co-authored-by: Martin Hoch <martin@littlerobot.de> Closes GH-11349 Closes GH-11305
43 lines
982 B
PHP
43 lines
982 B
PHP
--TEST--
|
|
Serialization of RC1 objects appearing in object graph twice
|
|
--FILE--
|
|
<?php
|
|
|
|
function rcn() {
|
|
$root = new stdClass;
|
|
$end = new stdClass;
|
|
$root->a = [$end];
|
|
$root->b = $root->a;
|
|
unset($end);
|
|
echo serialize($root), "\n";
|
|
}
|
|
|
|
function rcn_rc1() {
|
|
$root = new stdClass;
|
|
$end = new stdClass;
|
|
$root->a = [[$end]];
|
|
$root->b = $root->a;
|
|
unset($end);
|
|
echo serialize($root), "\n";
|
|
}
|
|
|
|
function rcn_properties_ht() {
|
|
$object = new stdClass;
|
|
$object->object = new stdClass;
|
|
$array = (array) $object;
|
|
$root = [$object, $array];
|
|
unset($object);
|
|
unset($array);
|
|
echo serialize($root), "\n";
|
|
}
|
|
|
|
rcn();
|
|
rcn_rc1();
|
|
rcn_properties_ht();
|
|
|
|
?>
|
|
--EXPECT--
|
|
O:8:"stdClass":2:{s:1:"a";a:1:{i:0;O:8:"stdClass":0:{}}s:1:"b";a:1:{i:0;r:3;}}
|
|
O:8:"stdClass":2:{s:1:"a";a:1:{i:0;a:1:{i:0;O:8:"stdClass":0:{}}}s:1:"b";a:1:{i:0;a:1:{i:0;r:4;}}}
|
|
a:2:{i:0;O:8:"stdClass":1:{s:6:"object";O:8:"stdClass":0:{}}i:1;a:1:{s:6:"object";r:3;}}
|