php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #65806 unserialize fails with object which is referenced multiple times
Submitted: 2013-10-02 07:56 UTC Modified: 2013-10-04 14:02 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: sysadmin at interexa dot de Assigned:
Status: Not a bug Package: *General Issues
PHP Version: 5.4.20 OS: linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: sysadmin at interexa dot de
New email:
PHP Version: OS:

 

 [2013-10-02 07:56 UTC] sysadmin at interexa dot de
Description:
------------
Running the testscript fails. The second reference to Object A is null after unserialize.
This happens in PHP 5.4.x as well as  PHP 5.5.4.

Maybe this bug is related to bug 65724. 

Test script:
---------------
<?php
class myObjA {}
class myObjB {
    public $attrA;
    public $attrB;
}
class myObjC {
    public $attrC;
    public $attrD;
}
class myList {
    private $_serialized;
    private $_obj;

    public function __construct($obj)
    {
        $this->_obj = $obj;
        $this->_serialized = serialize($this->_obj);
    }
    public function get()
    {
        return unserialize($this->_serialized);
    }
    public function __sleep()
    {
        $this->_serialized = serialize($this->_obj);
        return array(
            "\0" . __CLASS__ . "\0_serialized",
        );
    }
}

echo "SCRIPT START" . PHP_EOL;

$objA = new myObjA();
$objB = new myObjB();
$objC = new myObjC();

$objB->attrA = new ArrayIterator();
$objB->attrB = $objA;

$objC->attrC = $objB;
$objC->attrD = $objA;

$list = new myList($objC);

echo 'check ' . check($list->get()) . PHP_EOL;

file_put_contents('serialize.dmp', serialize($list));

echo "start serialize/unserialize" . PHP_EOL;
$newList = unserialize(serialize($list));
echo "finish serialize/unserialize" . PHP_EOL;

//after unserialize the property myObjC::attrD is null instead of expected object
echo 'check ' . check($newList->get()) . PHP_EOL;

echo "SCRIPT END" . PHP_EOL ;

function check(myObjC $obj) {

    if (!is_object($obj->attrC)) {
        return 'failed (myObjC::attrC => ' . var_export($obj->attrC, true) . ')';
    }
    if (!is_object($obj->attrD)) {
        return 'failed (myObjC::attrD => ' . var_export($obj->attrD, true) . ')';
    }
    return 'successful';
}

Expected result:
----------------
SCRIPT START
check successful
start serialize/unserialize
finish serialize/unserialize
check successful
SCRIPT END


Actual result:
--------------
SCRIPT START
check successful
start serialize/unserialize
finish serialize/unserialize
check failed (myObjC::attrD => NULL)
SCRIPT END


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2013-10-04 14:02 UTC] mike@php.net
-Status: Open +Status: Not a bug
 [2013-10-04 14:02 UTC] mike@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The serialization context is reset and non-recursive in __sleep and __wakeup, so if you serialize something in __sleep, you have to unserialize it in __wakeup.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Jul 25 10:01:23 2021 UTC