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 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 Previous Comments: ------------------------------------------------------------------------ [2012-03-26 09:05:57] s...@php.net 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] s...@php.net 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] s...@php.net 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 :) ------------------------------------------------------------------------ [2012-02-13 19:16:25] sjon at hortensius dot net @andrew at localcoast dot net Did you try to remove all __toString methods from your application? If that didn't fix it you are experiencing another bug and will probably need to generate a small reproducing script yourself @pada at hrz dot tu-chemnitz dot de your problem has nothing to do with this bug, You are simply demonstrating a recursive loop. ------------------------------------------------------------------------ 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