php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67452 clone and serialize issue
Submitted: 2014-06-16 11:14 UTC Modified: 2017-01-01 20:40 UTC
From: remi@php.net Assigned:
Status: Duplicate Package: *General Issues
PHP Version: 5.4+ OS: GNU/LInux (32 bits)
Private report: No CVE-ID: None
 [2014-06-16 11:14 UTC] remi@php.net
Description:
------------
On 32bits build, ext/standard/tests/serialize/bug64146.phpt fails.



Test script:
---------------
bug64146.phpt with a dump of the serialized string.

Expected result:
----------------
On 64 bits we have (test OK)

string(108) "O:1:"A":1:{s:1:"a";a:2:{i:0;C:1:"B":24:{O:1:"C":1:{s:1:"c";i:1;}}i:1;C:1:"B":24:{O:1:"C":1:{s:1:"c";i:2;}}}}"



Actual result:
--------------
On 32 bits we have (failed test)

string(87) "O:1:"A":1:{s:1:"a";a:2:{i:0;C:1:"B":24:{O:1:"C":1:{s:1:"c";i:1;}}i:1;C:1:"B":4:{r:4;}}}"


Patches

serialize.patch (last revision 2014-06-17 09:56 UTC by remi@php.net)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-16 11:16 UTC] remi@php.net
Enabling debug output in php_add_var_hash(),
with (type, zend_objects_get_address, handle): var_no

+ add var (5, f6e11b18,        6): 1
+ add var (4,        0,        0): 2
+ add var (5, f6e1169c,        7): 3
+ add var (5, f6e13d94,        b): 4
+ add var (1,        0,        0): 5
+ add var (5, f6e1175c,        9): 6
- had var (5, f6e13d94,        b): 4
 [2014-06-16 11:33 UTC] remi@php.net
-PHP Version: 5.5.13 +PHP Version: 5.4+
 [2014-06-16 11:34 UTC] remi@php.net
This test is failing since introduced in 5.4.22
 [2014-06-17 09:56 UTC] remi@php.net
The following patch has been added/updated:

Patch Name: serialize.patch
Revision:   1402999007
URL:        https://bugs.php.net/patch-display.php?bug=67452&patch=serialize.patch&revision=1402999007
 [2014-06-17 09:58 UTC] remi@php.net
This first patch seems to fix this runtime issue, and don't break other serialize tests.

This is not a perfect solution, as handle free list is ignored.
 [2014-06-20 12:46 UTC] mbeccati@php.net
Bug was reproducted on NetBSD i386. The patch fixes the issue.
 [2014-12-12 16:42 UTC] nikic@php.net
Apart from the free_list issue, the patch has the additional problems that object R refs will not be created for objects created in serialize(). Consider the following script:

<?php

class Test implements Serializable {
    public function serialize() {
        $obj = new stdClass;
        return serialize([$obj, $obj]);
    }
    public function unserialize($str) {
        var_dump(unserialize($str));
    }
}

unserialize(serialize(new Test));

Here an array with two identical objects is serialized and as such it also should unserialize to the same object.

Current behavior:

~/dev/php-5.6$ sapi/cli/php t18.php 
array(2) {
  [0]=>
  object(stdClass)#2 (0) {
  }
  [1]=>
  object(stdClass)#2 (0) {
  }
}

After patch:

~/dev/php-5.6$ sapi/cli/php t18.php 
array(2) {
  [0]=>
  object(stdClass)#2 (0) {
  }
  [1]=>
  object(stdClass)#3 (0) {
  }
}

So just excluding objects created during serialize() might solve the test failure, but will introduce problems in other cases.

I think the only way to fix this issue is to retain a reference to all objects that are serialized and drop it after serialization is finished. This avoids the possibility that object handles or memory addresses are reused during serialization. This is how this was fixed in PHP 7:

    https://github.com/php/php-src/commit/8be73f2650582423ec1d3c4b65a77c450f6683a0
    https://github.com/php/php-src/commit/75860fa8e1d8ce0c9fd2b505bf7663a4936a7a39

However the same approach is likely not feasible in 5.x due to ABI restrictions.
 [2015-01-23 17:30 UTC] aaron dot hamid at gmail dot com
I haven't looked at this patch but from discussion it looks related to #66085 https://bugs.php.net/bug.php?id=66085 I had an experimental fix for that IIRC in the 5.6 line:

https://github.com/ahamid/php-src/commit/cfe3a0f543fb104d52cf684ddd65e68c3f521375

>I think the only way to fix this issue is to retain a reference to all objects that are serialized and drop it after serialization is finished. This avoids the possibility that object handles or memory addresses are reused during serialization.

Yes, I came to the same conclusion.
 [2015-01-23 18:05 UTC] aaron dot hamid at gmail dot com
For completeness my pull request with some questions regarding impl: https://github.com/php/php-src/pull/550
 [2017-01-01 20:40 UTC] nikic@php.net
-Status: Open +Status: Duplicate
 [2017-01-01 20:40 UTC] nikic@php.net
As mentioned in comments, this is a duplicate of bug #66085.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Oct 17 01:03:35 2021 UTC