php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #75655 Segfault when using magic methods AND reference to self in property
Submitted: 2017-12-08 18:59 UTC Modified: 2017-12-14 15:12 UTC
Votes:17
Avg. Score:4.9 ± 0.5
Reproduced:15 of 16 (93.8%)
Same Version:13 (86.7%)
Same OS:13 (86.7%)
From: michael at imagely dot com Assigned: cmb (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 7.2.0 OS: Any
Private report: No CVE-ID: None
 [2017-12-08 18:59 UTC] michael at imagely dot com
Description:
------------
This will produce a segfault in PHP 7.2, 7.1.12, and 7.0.26. Any other versions will execute this and exit clean.

The example code is extracted from NextGEN Gallery, a popular WordPress plugin with over 1 million installs. The code is used extensively by the plugin and therefore causing major havoc.

If you remove "$this->object = $this", the segfault will not occur.

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

class ExtensibleObject
{
	var  $object = NULL;

	function __construct()
	{
		$this->object = $this;
	}
}


class C_DataMapper_Model extends ExtensibleObject
{
	var $_stdObject = NULL;
	
	function __construct()
	{
		parent::__construct();
		$this->_stdObject = new stdClass();
	}

	function &__get($property)
	{
		if (isset($this->_stdObject->$property)) {
			$retval = &$this->_stdObject->$property;
			return $retval;
		}
		else {
			// We need to assign NULL to a variable first, since only
			// variables can be returned by reference
			$retval = NULL;
			return $retval;
		}
	}

	function &__set($property, $value)
	{
		$retval = $this->_stdObject->$property= $value;
		return $retval;
	}


	function __isset($property_name)
	{
		return isset($this->_stdObject->$property_name);
	}
}

class C_Display_Type extends C_DataMapper_Model
{
	function __construct()
	{
		parent::__construct();
	}

	function &__get($property)
	{
		if (isset($this->settings) && isset($this->settings[$property])) {
			$retval = &$this->settings[$property];
			return $retval;
		}
		else return parent::__get($property);
	}
}

// This will segfault
$display_type = new C_Display_Type();
if (!isset($display_type->settings)) $display_type->settings = array();
for ($i=0; $i<10; $i++) {
	$key = 'foo_'.$i;
	$display_type->settings[$key] = 'bar';
}
var_dump($display_type->settings);



Expected result:
----------------
array(10) {
  ["foo_0"]=>
  string(3) "bar"
  ["foo_1"]=>
  string(3) "bar"
  ["foo_2"]=>
  string(3) "bar"
  ["foo_3"]=>
  string(3) "bar"
  ["foo_4"]=>
  string(3) "bar"
  ["foo_5"]=>
  string(3) "bar"
  ["foo_6"]=>
  string(3) "bar"
  ["foo_7"]=>
  string(3) "bar"
  ["foo_8"]=>
  string(3) "bar"
  ["foo_9"]=>
  string(3) "bar"
}

Actual result:
--------------
Segmentation fault (core dumped)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-12-08 20:42 UTC] michael at imagely dot com
Related to Bug #75573
 [2017-12-10 18:53 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2017-12-10 18:53 UTC] cmb@php.net
Can you please check whether this issue has been resolved in the
latest RCs?  See <http://qa.php.net/> and
<http://windows.php.net/qa/>, respectively.
 [2017-12-14 14:55 UTC] michael at imagely dot com
-Status: Feedback +Status: Assigned
 [2017-12-14 14:55 UTC] michael at imagely dot com
Yes it has. Thanks!
 [2017-12-14 15:12 UTC] cmb@php.net
-Status: Assigned +Status: Closed
 [2017-12-14 15:12 UTC] cmb@php.net
Thanks!  Closing.
 
PHP Copyright © 2001-2018 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC