To be honest I had not thought about the bad side of this use, i guess it could be possible to not return upper than a try/catch block (then return a fatal error if our code is trying to returns upper than a try/catch block).
Now the practical example: // Code i have the hand on function main() { foo('bar'); echo "I'm an angel !"; } function bar() { echo "I'm not Evil"; } //Code i don't have the hand on (like a MVC core) function foo($thing) { // make_love_dont_war(); call_user_func($thing); //Do some stuff i don't want to execute echo 'evil'; } function make_love_dont_war() { echo 'Make love, dont war.'; } You get it ? Georges.L 2015-03-21 17:07 GMT+01:00 John Bafford <jbaff...@zort.net>: > > On Mar 21, 2015, at 10:17, Georges.L <cont...@geolim4.com> wrote: > > > The main purpose of this RFC is *not* to improve the exception system of > > PHP but to improve the code logic/hierarchy. > > > >>> Hi php internals, > >>> > >>> After some long and deep research i finally decided to write my first > RFC > >>> about a feature i'd be interested to be improved in the php core: > *Nested > >>> enclosing returns* > > Georges, > > This would make simply looking at code and reasoning about what it does > impossible. > > At present, if I have the following code: > > function foo() { > if(doSomething()) { > success(); > } else { > failure(); > } > > return 42; > } > > try { > bar(foo()); > } catch($ex) { > } > > Then I can make the following true statements about this code: > * foo always calls doSomething() > * foo always calls either success() or failure(), based on the > result of doSomething() > * foo always returns 42 > * bar is always called (with foo’s return value, 42) > * Alternatively to the above, any of the called functions may > throw an exception, which will be caught by the catch block > > If any of doSomething(), success(), failure(), or bar() can arbitrarily > return to some higher calling scope, then the only thing I can say for sure > is that doSomething() is called, after which my application could be in > some dangerously inconsistent state because I have no idea what will be > executed next. > > This then provides significant security concerns. For example, if we have > this: > > function API_Function_With_Callback($callback) { > try { > $callback(); > > //do more stuff > > return true; > } catch($ex) { > //do error stuff > > return false; > } > } > > function doEvil() { > $sentinel = //some unique value > > $result = API_Function_With_Callback(function() use($sentinel) { > $backtrace = debug_backtrace(); > $nestingLevel = //determine nesting level from backtrace > if($nestingLevel == 2) return $sentinel, 2; > else if($nestingLevel == 3) return $sentinel, 3; > else if($nestingLevel == 4) return $sentinel, 4; > // etc > } > > // Exploit inconsistent state of Call_API_Function here > if($result === $sentinel) { … } > } > > Then we can short-circuit code from some other library which isn’t > prepared to deal with this kind of hijacking. More seriously, this sort of > hijacking *can’t* be defended against (at least not without a weakening of > your original proposal). Any function that takes a callback is potentially > vulnerable to this sort of attack. > > > Can you suggest an actual, practical, example, where this would be such a > benefit as to override the inherent difficulty about reasoning about this > code, and the potential security concerns? Are there any other languages > that make something like this possible? > > I suspect that any code that could be “improved” with this functionality > is already in significant need of improvement by more conventional means. > > -John > >