php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61042 unserialize issue
Submitted: 2012-02-10 11:47 UTC Modified: 2012-02-13 11:20 UTC
From: vigano dot n at clxeurope dot com Assigned:
Status: Duplicate Package: Arrays related
PHP Version: 5.3.10 OS: Linux Centos
Private report: No CVE-ID: None
 [2012-02-10 11:47 UTC] vigano dot n at clxeurope dot com
Description:
------------
It seems that, using PHP 5.3.9/10, an unserialized object is not properly cast to array. 


Test script:
---------------
The following code gives different results using PHP 5.3.8 and PHP 5.3.9/10:

$arr = (object)array("value");
$uns = (array)unserialize(serialize($arr));
var_dump($uns);
var_dump(isset($uns[0]));



Expected result:
----------------
Using PHP 5.3.8:

array(1) { [0]=> string(5) "value" } bool(true)


Actual result:
--------------
Using PHP 5.3.9/10:

array(1) { ["0"]=> string(5) "value" } bool(false)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-02-10 12:01 UTC] cataphract@php.net
The bug is not in unserialize; the object is correctly unserialized, with the rule that objects only have string properties correctly enforced (this was not enforced before 5.3.9 though: see bug #55798). The problem is that these strings are not converted to numbers when casting to an array. This is a known problem and unfortunately the main opinion seems to be this ought not to be fixed due to performance issues.
 [2012-02-10 12:01 UTC] cataphract@php.net
-Status: Open +Status: Duplicate
 [2012-02-10 12:14 UTC] vigano dot n at clxeurope dot com
Anyway the problem affects only unserialized and cast objects. 
The following code works properly also with PHP 5.3.9/10:

$arr1 = array("0" => "string");
var_dump(isset($arr1["0"]));
var_dump(isset($arr1[0]));

returning:

bool(true) bool(true)
 [2012-02-10 12:22 UTC] vigano dot n at clxeurope dot com
In addition, to be honest I don't believe hat this problem "is that these strings are not converted to numbers when casting to an array". 

The following code, where conversion is not required, doesn't work as well:

$arr = (object)array("value");
$uns = (array)unserialize(serialize($arr));
var_dump($uns);
var_dump(isset($uns["0"]));

result:
array(1) { ["0"]=> string(5) "value" } bool(false)
 [2012-02-10 13:07 UTC] vigano dot n at clxeurope dot com
A possible workaround is serializing and unserializing again. Look at this piece of code:
$arr = (object)array("value0", "value1");
$uns = unserialize(serialize((array)unserialize(serialize($arr))));
var_dump($uns);
var_dump(isset($uns["0"]));
var_dump(isset($uns[0]));
var_dump(isset($uns["1"]));
var_dump(isset($uns[1]));

The result is:
array(2) { [0]=> string(6) "value0" [1]=> string(6) "value1" } bool(true) bool(true) bool(true) bool(true) 

This definitively confirm my idea that bug #55798 has nothing to do with this issue.
 [2012-02-13 11:20 UTC] cataphract@php.net
Again:

The reason why

$arr = (object)array("value");
$uns = (array)unserialize(serialize($arr));
var_dump($uns);
var_dump(isset($uns["0"]));

does not work, but this does

$arr = (object)array("value");
$uns = (array)$arr;
var_dump($uns);
var_dump(isset($uns["0"]));

is actually because the object $arr is broken (has a numeric property), while this is fixed by the composition of serialize/unserialize (since 5.3.9).

The bug you're experiencing is unrelated to unserialize, it's just that there used to be a bug in unserialize that would cancel out another bug that still exists, and that you can reproduce with:

//$arr = (object)array("value");
$arr = new stdClass;
$arr->{'0'} = "value";
//$uns = (array)unserialize(serialize($arr));
$uns = (array)$arr;
var_dump($uns);
var_dump(isset($uns["0"]));
 [2012-04-09 18:32 UTC] spamfry at gmail dot com
I am experiencing this bug in PHP 5.3.10. As previously mentioned, both 
isset($uns[0]) and isset($uns["0"]) return false, so this is not merely a matter 
of the data type of the array key, so it appears to be different from what is 
described in #55798. Was the issue resolved when #55798 was resolved?
 [2012-04-09 18:38 UTC] spamfry at gmail dot com
This seems to be related, even though I'm in PHP 5.3.8, and I'm not using 
unserialize() at all:

$obj = new stdClass;
$obj->{0} = 'foo';
var_dump(isset($obj->{0}));
$arr = (array)$obj;
var_dump($arr);
var_dump(isset($arr[0]));

Output:

bool(true)
array(1) {
  ["0"]=>
  string(3) "foo"
}
bool(false)

So apparently you can't access numeric properties after casting an object to an 
array.
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Wed Nov 14 11:01:25 2018 UTC