php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70733 int/string conversion bug in arrays
Submitted: 2015-10-17 15:43 UTC Modified: 2015-12-23 23:18 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:0 (0.0%)
From: bfanger at gmail dot com Assigned:
Status: Duplicate Package: Scripting Engine problem
PHP Version: irrelevant OS: El Capitan
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: bfanger at gmail dot com
New email:
PHP Version: OS:

 

 [2015-10-17 15:43 UTC] bfanger at gmail dot com
Description:
------------
Reading and writing to an array could lead to new array entries (with an integer key) instead of overwriting the value.

This even leads weird json output using which uses same key twice, but that's an other issue.

Test script:
---------------
$object = json_decode('{"200": true}');
$data = get_object_vars($object);
$data['200'] = false;
echo json_encode($data, JSON_PRETTY_PRINT);


Expected result:
----------------
{
    "200": false
}

Actual result:
--------------
{
    "200": true,
    "200": false
}

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-17 16:27 UTC] ab@php.net
-PHP Version: 7.0.0RC5 +PHP Version: irrelevant
 [2015-10-17 16:27 UTC] ab@php.net
Reproduced even with 5.5.

Thanks.
 [2015-10-18 07:19 UTC] laruence@php.net
actually, this is not something new...

because, there are string "200" and interge 200 in the same array.

which is an knew issue.
 [2015-10-18 09:29 UTC] bfanger at gmail dot com
@laruence But the code snippet doesn't use integers anywhere, but php7 somehow decides to use the integer 200 instead of the given '200'.

PHP 5.3, 5.3, 5.4, 5.5, 5.6 doesn't have this issue.
 [2015-10-18 11:35 UTC] laruence@php.net
that is get_object_vars now reuse the same array of the properties table of stdclass..

like: 
<?php
$object = json_decode('{"200": true}');
$data = (array)($object);
var_dump($data);
$data['200'] = false;
var_dump($data);
echo json_encode($data, JSON_PRETTY_PRINT);


this will result the same result both on php-5.6 and php7

:<
 [2015-11-28 11:23 UTC] bfanger at gmail dot com
So the bug is even older, when you use `(array)` instead of `get_object_vars()` :-(
Sound like an opportunity to fix it in PHP7 which suppose to have better types. ;-)

I've found some workarounds make the following code work reliably across php versions:


$data["200"] = false;


Workaround 1: 
  $data = unserialize(serialize((array) $object));

Workaround 2: 
  $data = unserialize(serialize(get_object_vars($object)));

Workaround 3:
  $data = json_decode(json_encode($object), true);
 [2015-12-23 23:18 UTC] ajf@php.net
-Status: Open +Status: Duplicate
 [2015-12-23 23:18 UTC] ajf@php.net
Duplicate of bug #66173
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Aug 06 02:01:24 2020 UTC