Hi!

> a) Error handlers can (and often do) throw. E.g. it is possible to convert
> the two recoverable fatal errors that __toString() currently throws into
> exceptions and end up in the situation you describe, only with even less
> safety and more leaks. However this applies to all occurrences of
> zend_error or php_error_docref that generate a non-fatal error. From a
> quick grep I estimate we have about 4000 places in the codebase where this
> can occur and I'm sure many of them do not check for EG(exception)
> immediately after throwing the error.
> 
> b) Destructors can throw. We have approximately 2500 places in php-src
> destroying a zval, which could potentially throw. I don't think I've ever
> seen an EG(exception) check after a zval_ptr_dtor().

You don't usually use the value being destroyed after zval_ptr_dtor().
You could, however, use the value that was supposed to be converted
after __toString, and you probably are if you're converting it. The
problem is not that exception is thrown, the problem is that the code
assumes there's some workable value and there's none or at least not the
value it expected.

With error handlers, it is trickier but the code that produces the error
usually does not expect everything to be fine after the error handler is
done - on the contrary, it explicitly expects it *not* to be fine, since
it just reported that something is not fine by invoking the error
handler! Of course, we have there all kinds of issues with error
handlers messing with the environment, but it's much harder to cause
this problem by accident.

The problem, as I see it, is not the throwing of exception by itself,
but the fact that the code assumes the defined state of the variable
being converted, but when exception is thrown, we don't get that state,
but we also don't know something bad happened.

Of course, we could do something like set the value to empty string, but
since again there's no check there the code would just assume we've got
legitimate conversion to empty string - which is not the same as "we've
got error" and could lead to very unexpected consequences (such as
somebody erroneously supplying object as a password and system treating
it as empty password).

> If you want to protect against side-effects after exceptions in critical
> places like database interaction, we can introduce exception checks right
> before the operation is executed and prevent anything bad from happening

I don't see how this is possible - we have no idea which places can be
"critical" - any interaction with now-undefined variable could lead to a
disaster downstream.
-- 
Stas Malyshev
smalys...@gmail.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to