php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50299 method is called in context of another object
Submitted: 2009-11-25 21:10 UTC Modified: 2016-07-14 12:38 UTC
Votes:3
Avg. Score:3.3 ± 1.7
Reproduced:2 of 3 (66.7%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: shepik at yandex dot ru Assigned: dmitry (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3SVN-2009-11-25 (snap) OS: *
Private report: No CVE-ID: None
 [2009-11-25 21:10 UTC] shepik at yandex dot ru
Description:
------------
I tried this in php 5.3.2-dev (snapshot from 2009-11-19, latest php for windows available) and in php 5.3.0 on linux.

I tried to do something like 'lazy object instantiation', and found this strange behaviour of php.

Method "valid" declared in "lazyNew" class is called in context of instance of "ArrayIterator" class.

Reproduce code:
---------------
<?php
class lazyNew implements Iterator {
	private $obj = null;
	private $func ;
	public function __construct($func) {
		$this->func = $func;
	}
	public function init() {
		if ($this->obj === null) {
			$func = $this->func;
			$this->obj = $func();
		}
		return $this->obj;
	}
	public function current() {
		return $this->init()->current();
	}
	public function valid() {
		echo "valid on ".get_class($this)."\n";
		//also try var_dump($this)
		return $this->init()->valid();
	}
	public function next() {
		return $this->init()->next();
	}
	public function key() {
		return $this->init()->key();
	}
	public function rewind() {
		echo "rewind on ".get_class($this)."\n";
		return $this->init()->rewind();
	}
}


$P = new lazyNew(function() use (&$P) {
	return $P = new ArrayIterator(array(1,2,3,4,5));
});

foreach ($P as $val) echo($val);

?>

Expected result:
----------------
rewind on lazyNew
valid on lazyNew
12345

Actual result:
--------------
rewind on lazyNew
valid on ArrayIterator

Fatal error: Call to undefined method ArrayIterator::init() in /storage1/www/htdocs/evectio/scripts/test.php on line 20


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-11-25 21:17 UTC] shepik at yandex dot ru
And if change code to
$P = new lazyNew(function() use (&$P) {
	$v = new ArrayIterator(array(1,2,3,4,5));
	$P = null;
	return $v;
});

instead of fatal error, or "12345", or something else, i get segmentation fault.
 [2009-11-25 21:56 UTC] shepik at yandex dot ru
(and i don't know if i should select "SPL related" or "reproducible crash" category, so if i'm wrong with selecting "SPL", please correct me)
 [2009-11-26 10:18 UTC] kalle@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a backtrace to see what is happening behind the scenes. To
find out how to generate a backtrace, please read
http://bugs.php.net/bugs-generating-backtrace.php for *NIX and
http://bugs.php.net/bugs-generating-backtrace-win32.php for Win32

Once you have generated a backtrace, please submit it to this bug
report and change the status back to "Open". Thank you for helping
us make PHP better.


 [2009-11-26 11:05 UTC] shepik at yandex dot ru
shepik@samoval ~/php-5.3-200911260930 $ gdb sapi/cli/php
GNU gdb 6.8 [..]
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) run test_variant2.php
Starting program: /home/shepik/php-5.3-200911260930/sapi/cli/php test_variant2.php
rewind on Foo

Program received signal SIGSEGV, Segmentation fault.
0x083a67d7 in zend_get_class_entry (zobject=0x8e536c0) at /home/shepik/php-5.3-200911260930/Zend/zend_API.c:230
230             if (Z_OBJ_HT_P(zobject)->get_class_entry) {
(gdb) bt
#0  0x083a67d7 in zend_get_class_entry (zobject=0x8e536c0) at /home/shepik/php-5.3-200911260930/Zend/zend_API.c:230
#1  0x083bef20 in zend_call_method (object_pp=0xbfc6b3cc, obj_ce=0x8e50038, fn_proxy=0x8e50170,
    function_name=0x87194c5 "valid", function_name_len=5, retval_ptr_ptr=0xbfc6b3c8, param_count=0, arg1=0x0,
    arg2=0x0) at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:88
#2  0x083bf1d9 in zend_user_it_valid (_iter=0x8e53754)
    at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:163
#3  0x08446999 in ZEND_FE_RESET_SPEC_CV_HANDLER (execute_data=0x8e7dba0)
    at /home/shepik/php-5.3-200911260930/Zend/zend_vm_execute.h:22653
#4  0x083d0b7e in execute (op_array=0x8e51a84) at /home/shepik/php-5.3-200911260930/Zend/zend_vm_execute.h:104
#5  0x083a605e in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/shepik/php-5.3-200911260930/Zend/zend.c:1194
#6  0x0833df90 in php_execute_script (primary_file=0xbfc6d8cc)
    at /home/shepik/php-5.3-200911260930/main/main.c:2231
#7  0x0846b874 in main (argc=2, argv=0xbfc6da24) at /home/shepik/php-5.3-200911260930/sapi/cli/php_cli.c:1190
 [2009-11-27 08:40 UTC] shepik at yandex dot ru
it seems that "rewind" and "valid" are called on $P variable and not on the contents of $P variable at the moment "foreach" was called.

#3 0x08397fe1 in zend_call_function (fci=0xbfdeeaf4, fci_cache=0xbfdeeac4)
at /home/shepik/php-5.3-200911260930/Zend/zend_execute_API.c:942
#4 0x083bef94 in zend_call_method (object_pp=0xbfdeeb60, obj_ce=0x8f20038, fn_proxy=0x8f20180,
function_name=0x871959d "rewind", function_name_len=6, retval_ptr_ptr=0x0, param_count=0, arg1=0x0, arg2=0x0)
at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:97
#5 0x083bf735 in zend_user_it_rewind (_iter=0x8f23754)
at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:261 

*(zval*)iter->it.data = {value = {lval = 1, dval = 5.6472996106671002e-268, str = {val = 0x1 <Address 0x1 out of bounds>,
len = 141731200}, ht = 0x1, obj = {handle = 1, handlers = 0x872a580}}, refcount__gc = 3, type = 5 '\005',
is_ref__gc = 1 '\001'}


now callind "valid":
#1 0x083bef20 in zend_call_method (object_pp=0xbfdeeb5c, obj_ce=0x8f20038, fn_proxy=0x8f20170,
function_name=0x87194c5 "valid", function_name_len=5, retval_ptr_ptr=0xbfdeeb58, param_count=0, arg1=0x0,
arg2=0x0) at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:88
#2 0x083bf1d9 in zend_user_it_valid (_iter=0x8f23754)
at /home/shepik/php-5.3-200911260930/Zend/zend_interfaces.c:163

*(zval*)iter->it.data = {value = {lval = 0, dval = 8.4879831638610893e-314, str = {val = 0x0, len = 4}, ht = 0x0, obj = {handle = 0,
handlers = 0x4}}, refcount__gc = 2, type = 0 '\0', is_ref__gc = 1 '\001'}


(i don't know if this information is useful at all, but hope it is)
 [2016-07-14 12:38 UTC] dmitry@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: dmitry
 [2016-07-14 12:38 UTC] dmitry@php.net
The bug was fixed in PHP-7.0
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 20:01:32 2025 UTC