Edit report at https://bugs.php.net/bug.php?id=60701&edit=1
ID: 60701
Comment by: arjen at react dot com
Reported by: daan at react dot com
Summary: __toString() which stores $this reference triggers
segfault (with fix!)
Status: Assigned
Type: Bug
Package: Reproducible crash
Operating System: CentOS
PHP Version: 5.3.8
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
5.3.10/5.4.0 fixed original testcase; see http://3v4l.org/sc0mQ
5.3.11/5.4.1 fixed modified testcase; see http://3v4l.org/iYBMZ
Please close this issue and mark as fixed!
Previous Comments:
------------------------------------------------------------------------
[2012-04-02 09:53:08] arjen at react dot com
5.3.10 fixed the attached testcase, a more simple test now fails.
<?php
class A {
public $a;
public function __toString()
{
$this->a = $this;
return 'waa?';
}
}
$a = new A;
echo trim($a);
echo trim($a->a);
Results:
5.3.0 - 5.3.9 waa?1
5.3.10 waa? Warning: trim() expects parameter 1 to be string, unknown given in
/home/deployer/public_html/php/tmp/ba8096acaf18c52bc12e38619634c25b on line 14
5.4.0 Segmentationfault
------------------------------------------------------------------------
[2012-03-26 09:05:57] [email protected]
OK, I think I know what may be going on here. What you're getting as $this in
toString() is not a real $object but a copy what was generated by
SEPARATE_ZVAL_IF_NOT_REF() in parse_arg_object_to_string(). If you save this
copy, there might be trouble since it'd be destroyed by writeobj and later
cleanup of the function arguments. However, the patch proposed doesn't seem to
solve the problem completely since $this->test variable is still corrupted in
this scenario...
------------------------------------------------------------------------
[2012-03-26 08:38:59] [email protected]
I looked more into the code, and as far as I can see, the case where readobj ==
writeobj comes from parse_arg_object_to_string() - but there it is preceeded by
SEPARATE_ZVAL_IF_NOT_REF(arg); so I don't see how you can get refcount > 1
there
unless you have IS_REF. Something else is going on there...
------------------------------------------------------------------------
[2012-03-26 07:21:23] [email protected]
I'm not sure I understand the patch, especially this part:
if (readobj == writeobj) {
+ if (Z_REFCOUNT_P(readobj) <= 1)
{
+ INIT_PZVAL(writeobj);
+ }
zval_dtor(readobj);
It looks like you initializing the object and then immediately calling dtor on
it (since readobj == writeobj). Could you explain why and what you are trying
to
do there?
------------------------------------------------------------------------
[2012-02-13 19:48:38] pada at hrz dot tu-chemnitz dot de
@sjon: Now, I retried with the original Test script from daan.
This patch works for me too, thanks :)
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=60701
--
Edit this bug report at https://bugs.php.net/bug.php?id=60701&edit=1