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 <[email protected]>:
>
> On Mar 21, 2015, at 10:17, Georges.L <[email protected]> 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
>
>