php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78667 Segmentation fault when using clone in jsonSerilization method
Submitted: 2019-10-12 21:44 UTC Modified: 2019-10-13 13:55 UTC
From: aparcos at gmail dot com Assigned: cmb (profile)
Status: Not a bug Package: Class/Object related
PHP Version: Irrelevant OS: Irrelevant
Private report: No CVE-ID: None
 [2019-10-12 21:44 UTC] aparcos at gmail dot com
Description:
------------
A segmentation fault is going to happen when you accidentally uses clone inside the jsonSerialize method that implements JsonSerializable and return the new cloned object. If you uncomment the following test script,  you will see that is going to be called several times until the recursive call get exhausted and finish given the segmentation fault.



Test script:
---------------
<?php


class CloneThis implements JsonSerializable {
  public $date;

  public function jsonSerialize() {
        $clone = clone $this;
//      var_dump($this);

//        if ($this->date instanceof DateTime) {
 //               $clone->date = $this->date->format('Y.m.d');
   //     }
        return $clone;
  }
 
}


$variable = new CloneThis;
$variable->date = new DateTime();

echo json_encode($variable);












Expected result:
----------------
I think should be :
 1. or the current date. 
 2. or An error where many recursive calls are done (maybe)


Actual result:
--------------
////////////////////////////////
...strings removed

object(CloneThis)#52273 (1) {
  ["date"]=>
  string(10) "2019.10.12"
}
object(CloneThis)#52274 (1) {
  ["date"]=>
  string(10) "2019.10.12"
}
object(CloneThis)#52275 (1) {
  ["date"]=>
  string(10) "2019.10.12"
}
object(CloneThis)#52276 (1) {
  ["date"]=>
  string(10) "2019.10.12"
}
object(CloneThis)#52277 (1) {
  ["date"]=>
Segment violation


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-13 07:40 UTC] aparcos at gmail dot com
-Package: Class/Object related +Package: PHP Language Specification -Operating System: Debian 10 +Operating System: Irrelevant
 [2019-10-13 07:40 UTC] aparcos at gmail dot com
Changed affected OS & Package
 [2019-10-13 07:56 UTC] requinix@php.net
-Package: PHP Language Specification +Package: Class/Object related
 [2019-10-13 09:14 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Assigned To: +Assigned To: cmb
 [2019-10-13 09:14 UTC] cmb@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

Since the clone is also an instance of JsonSerializable, the code
causes infinite recursion, similar to

    function foo() {
        foo();
    }
    foo();

PHP deliberately does not catch this, but rather considers it to
be a programming error[1].  You can use Xdebug[2] to catch such
issues during development.

You can use something like get_object_vars()[3] instead of clone
to avoid recursion in the first place.

[1] <https://www.php.net/manual/en/functions.user-defined.php>
[2] <https://xdebug.org/docs/basic#max_nesting_level>
[3] <https://www.php.net/manual/en/function.get-object-vars.php>
 [2019-10-13 13:55 UTC] aparcos at gmail dot com
Ok! this is a programmer error but php should throw PHP Fatal Error, at least some known like:

PHP Fatal error:  Maximum function nesting level of '256' reached, aborting! in - on line 3
PHP Stack trace:
PHP   1. {main}() -:0
PHP   2. foo() -:6

but not a Segmentation Fault, doesn't?
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC