Bug #66085 [Ver]: in function serialize() there is irregular behaviour

From: Date: Sun, 01 Jan 2017 11:51:30 +0000
Subject: Bug #66085 [Ver]: in function serialize() there is irregular behaviour
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-206271@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=66085&edit=1 ID: 66085 Updated by: nikic@php.net Reported by: machine dot check dot exception at gmail dot com Summary: in function serialize() there is irregular behaviour Status: Verified Type: Bug Package: Arrays related Operating System: Windows 7 PHP Version: 5.5.5 Block user comment: N Private report: N New Comment: This bug has been fixed in PHP 7 by retaining all relevant zvals during serialization: https://github.com/php/php-src/blob/master/ext/standard/var.c#L629 Previous Comments: ------------------------------------------------------------------------ [2017-01-01 11:47:23] nikic@php.net Related To: Bug #63163 ------------------------------------------------------------------------ [2013-12-23 07:48:47] aaron dot hamid at gmail dot com sorry i mis-pasted in my last comment, of course there should be 'global $keep_ref;' at beginning of serialize(). ------------------------------------------------------------------------ [2013-12-23 07:43:38] aaron dot hamid at gmail dot com Yup, zval ids/addresses are getting reused. It looks like $tmp is getting collected after the test serialize() method. If I *prevent* the collection by keeping a reference to the inner $tmp in a global array, then I get the expected output: $keep_ref = array(); class test implements Serializable { public $a; public function __construct( $_val ){ $this->a = $_val; } public function serialize() { $tmp = (object) array(); $tmp->a = $this->a; array_push($keep_ref, $tmp); // keep hold of a reference echo serialize( $tmp ) . "\n"; return serialize( $tmp ); } } I tested with the 9 value array example here: http://3v4l.org/DJg0j Can anybody confirm? If zval id/address is used as the visited object key, and these are getting reused/replaced by garbage collection while walking the object graph, then I'm not sure how we can implement references across the entire object graph. Is there a way to temporarily disable collecting reference-counted objects? I see there is gc_disable/gc_enable that appears to only affect "circular" reference collector. ------------------------------------------------------------------------ [2013-12-23 07:00:39] aaron dot hamid at gmail dot com I debugged this some and discovered that this line is producing object(stdClass)'s with the same zval pointer and zend_objects_get_address address values (actually they alternate two previous values) after the second entry: $tmp = (object) array(); This causes the object to be detected as already encountered and the reference encoded. I don't understand how or why this should be the case, are value structures getting reused, is garbage collection occurring? If I comment out the encountered lookup in php_var_serialize_intern then the desired output is produced, although I assume that defeats the recursion prevention you are talking about bwoebi - is there any other insight you can shed on this? Is my understanding correct? ------------------------------------------------------------------------ [2013-12-16 17:32:05] will at johnstonclan dot net Another test case available here: https://bugs.php.net/bug.php?id=66292 ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=66085 -- Edit this bug report at https://bugs.php.net/bug.php?id=66085&edit=1

« previous php.bugs (#206271) next »