php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75393 Value not preserved when assign-adding an array to an object
Submitted: 2017-10-17 00:21 UTC Modified: 2021-07-07 17:30 UTC
From: bwoebi@php.net Assigned: cmb (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.0Git-2017-10-16 (Git) OS: Irrelevant
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
33 + 36 = ?
Subscribe to this entry?

 
 [2017-10-17 00:21 UTC] bwoebi@php.net
Description:
------------
Assign-adding an array to an object leads to an use-after-free.

Test script:
---------------
$o = new stdClass;
$o += [];

Expected result:
----------------
Notice: Object of class stdClass could not be converted to int in - on line 1
Fatal error: Uncaught Error: Unsupported operand types in -:1
Stack trace:
#0 {main}
  thrown in - on line 1


Actual result:
--------------
Invalid read

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-10-17 00:21 UTC] bwoebi@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: bwoebi
 [2017-10-17 01:42 UTC] bwoebi@php.net
-Status: Assigned +Status: Open -Assigned To: bwoebi +Assigned To:
 [2017-10-17 01:42 UTC] bwoebi@php.net
Unassigning myself, there's a deeper rabbit hole than expected. The fix I attempted for the attached test to give the expected result is causing memory leaks in other tests.
Also, related issue: $rsrc += 1; leaks the resource.


--TEST--
Bug #75393 (Crash when assign-adding an array to an object)
--FILE--
<?php

try {
        $o = new stdClass;
        $o += [];
} catch (\Error $e) {
        var_dump($e->getMessage(), $o);
}

?>
--EXPECTF--

Notice: Object of class stdClass could not be converted to int in %s on line %d
string(25) "Unsupported operand types"
object(stdClass)#1 (0) {
}
 [2017-10-17 03:49 UTC] laruence@php.net
I can not reproduce this....
 [2017-10-17 03:53 UTC] laruence@php.net
this seems already be fixed: https://3v4l.org/oF3Al
 [2017-10-17 10:15 UTC] bwoebi@php.net
@laruence: It doesn't crash with master, yes. But it still does with PHP 7.0 and  7.1.

Also $o must not be int(1), but must be an instanceof stdClass afterwards.
 [2017-10-17 10:34 UTC] laruence@php.net
why not?

<?php
$o = new Stdclass();
var_dump((int)$o);

output:
PHP Notice:  Object of class stdClass could not be converted to int in /tmp/1.php on line 3
int(1)

and for:
$o += []

we preparing operands first, then trying to do add, then result in unsupported operand, which seems reasonable to me
 [2017-10-17 10:36 UTC] laruence@php.net
of course I also understand why it should be an stdclass instance, it also make sense, but it will make the codes complex, and this is really a rarely wrong case, so I think choose the easy way is a good chioce here.
 [2017-10-17 11:07 UTC] bwoebi@php.net
-Summary: Crash when assign-adding an array to an object +Summary: Value not preserved when assign-adding an array to an object -Package: Reproducible crash +Package: Scripting Engine problem
 [2017-10-17 11:07 UTC] bwoebi@php.net
Similarly:

php -r 'set_error_handler(function() { throw new \Exception; }); $a = "2"; $a .= "a"; try { $a+=1; } catch (\Exception $e) { } var_dump($a);'
int(3)

(instead of string(2) "2a")

(turns out the crash has already been fixed in the most recent git, but not yet in the last release. - renaming thus.)
 [2019-02-14 11:27 UTC] nikic@php.net
Triage: Segfault fixed in supported versions, but the incorrect type conversion still takes place.
 [2021-07-07 12:23 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2021-07-07 12:23 UTC] cmb@php.net
This seems to be fixed as of PHP 8.0.0[1], and I don't think a
backport makes much sense at this point in time.  Or am I missiung
something?

[1] <https://3v4l.org/M8f4X>
 [2021-07-07 17:30 UTC] bwoebi@php.net
-Status: Feedback +Status: Closed
 [2021-07-07 17:30 UTC] bwoebi@php.net
Yeah, looks good now. Let's consider it fixed and not change the semantics of existing old versions.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 15:01:28 2024 UTC