Bug #72188 [Csd]: Nested try/finally blocks losing return value
| From: | dmitry@php.net | Date: | Fri, 13 May 2016 11:48:58 +0000 |
| Subject: | Bug #72188 [Csd]: Nested try/finally blocks losing return value | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-201067@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72188&edit=1
ID: 72188
Updated by: dmitry@php.net
Reported by: lee at saferite dot com
Summary: Nested try/finally blocks losing return value
Status: Closed
Type: Bug
Package: Unknown/Other Function
Operating System: Ubuntu 14.04
PHP Version: 7.0.6
Assigned To: dmitry
Block user comment: N
Private report: N
New Comment:
Fixed in master (PHP-7.1) brunch only.
Previous Comments:
------------------------------------------------------------------------
[2016-05-13 11:39:04] dmitry@php.net
Automatic comment on behalf of dmitry@zend.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=be071702b30e9ba9bf9f9c9831f3301af039b1d5
Log: Fixed bug #72188 (Nested try/finally blocks losing return value)
------------------------------------------------------------------------
[2016-05-11 15:19:31] laruence@php.net
the problem here is:
we have two entry to the outter finally, the one is FAST_CALL before return(1), and the other is
FAST_CALL before finally(2).
when we enter the finally block via the
return one, we set fast_call_var to
ZEND_RETURN, but later, the ZEND_FAST_CALL in inner finally override it to its own return address.
later, when return from inner finally, it will return to the (2) which is calculated during
compiling time. thus bug shows up.
we could check fast_call_var's return address in ZEND_FAST_CALL to fix this particular problem,
but the problem is, we allocate fast_call_var in temp var now, there is no initialization mechanism
for it. which means, we can not do "check".
@Dmitry, what do you think?
thanks
------------------------------------------------------------------------
[2016-05-11 14:29:57] nikic@php.net
So, as I understand it the problem is that the FAST_CALL<FROM_FINALLY> of the inner finally
block will indiscriminately set the fast_call opline to the FAST_CALL of the outer finally block,
even though this is not necessarily the FAST_CALL that was actually used to enter it (e.g. in this
instance).
I was wondering why this worked on PHP 5.6 as IIRC the handling wasn't very different. It looks
like it's just an accident of fate that this particular code works there. This similar example
doesn't: https://3v4l.org/DsLLE
The only solution to this I see is to use different fast_call temporaries for each nesting level of
finally-in-finally. We also need this to solve a similar issue with exceptions, though I can't
seem to find the bug report for that just now (maybe in private discussions?).
------------------------------------------------------------------------
[2016-05-11 07:48:31] laruence@php.net
@nikic what do you think ? I don't see a easy to fix it..
------------------------------------------------------------------------
[2016-05-11 07:46:19] laruence@php.net
fast_call in before finally overfide the return address set by the fast_call before zend_return.
------------------------------------------------------------------------
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=72188
--
Edit this bug report at https://bugs.php.net/bug.php?id=72188&edit=1