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

From: Date: Mon, 23 Dec 2013 07:43:38 +0000
Subject: Bug #66085 [Com]: in function serialize() there is irregular behaviour
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-183441@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 Comment by: aaron dot hamid at gmail dot com 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: 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. Previous Comments: ------------------------------------------------------------------------ [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 ------------------------------------------------------------------------ [2013-11-14 11:27:40] bwoebi@php.net That actually is more complicated than I thought. If I fix that, the recursion prevention doesn't work anymore in other edge cases. Another developer might feel free to fix this. ------------------------------------------------------------------------ [2013-11-13 21:01:33] bwoebi@php.net I see; thank you for the report, I'll investigate further tomorrow. Seems the recursion prevention is buggy. Maybe it needs an extra stack for every serialize() call. ------------------------------------------------------------------------ [2013-11-13 20:43:19] machine dot check dot exception at gmail dot com The bug is there. Check this: http://3v4l.org/DJg0j It looks like it is a problem with memory allocation. Windows and linux allocate in different ways, that's why probably windows "crashes" earlier than linux (in maybe any overflow?). ------------------------------------------------------------------------ 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 (#183441) next »