From: mark at metrofindings dot com
Operating system: linux
PHP version: 5.2.5
PHP Bug Type: Scripting Engine problem
Bug description: Core exceptions are actually E_WARNINGs first
Description:
------------
Core exceptions, those generated by core classes in the PHP engine
itself and not user defined PHP code, are treated exactly as
E_WARNING errors before any exception related routines are called
when a custom error handler is being used.
This is a problem on 2 fronts:
1. It is different than user generated exceptions (throw new
Exception())
2. It is impossible to distinguish a core exception and a true
E_WARNING in a custom error handler (set_error_handler()).
The zend engine portion of the error handling code does not respect
PG(error_handling) settings, like EH_THROW. The Zend engine portion
of error handling (zend_error) calls any user defined error
handlers, *then* it calls php_error_cb (which properly checks for
throwable exceptions).
Here is a patch to php-5.2.5/main/main.c to check for exceptions
before calling zend's "PG(error_handling) unaware" error routine.
--- orig-5.2.5/main/main.c 2008-02-05 14:14:51.000000000 -0500
+++ php-5.2.5/main/main.c 2008-02-05 14:09:05.000000000 -0500
@@ -717,9 +715,35 @@
ZVAL_STRINGL(tmp, buffer, buffer_len, 1);
zend_hash_update(EG(active_symbol_table), "php_errormsg",
sizeof("php_errormsg"), (void **) &tmp, sizeof(zval *), NULL);
}
- efree(buffer);
- php_error(type, "%s", message);
+ //throw exceptions first before nomal zend_error
+ if (PG(error_handling) == EH_THROW && !EG(exception)) {
+ switch (type) {
+ case E_ERROR:
+ case E_CORE_ERROR:
+ case E_COMPILE_ERROR:
+ case E_USER_ERROR:
+ case E_PARSE:
+ /* fatal errors are real errors and
cannot be made exceptions */
+ break;
+ case E_STRICT:
+ /* for the sake of BC to old damaged
code */
+ break;
+ case E_NOTICE:
+ case E_USER_NOTICE:
+ /* notices are no errors and are not
treated as such like E_WARNINGS */
+ break;
+ default:
+ /* throw an exception if we are in
EH_THROW mode
+ * but DO NOT overwrite a pending
exception
+ */
+
zend_throw_error_exception(PG(exception_class), buffer, 0, type
TSRMLS_CC);
+ }
+ } else {
+ php_error(type, "%s", message);
+ }
+
+ efree(buffer);
efree(message);
}
/* }}} */
--end of patch--
Reproduce code:
---------------
<?php
function handleError($n, $m, $f, $l) {
//no difference between excpetions and E_WARNING
echo "user error handler: e_warning=".E_WARNING." num=".$n."
msg=".$m." line=".$l."\n";
return true;
//change to return false to make the "catch" block execute;
}
set_error_handler('handleError');
//turn off to make try/catch work normally
//comment this whole try/catch out to see new DateTimeZone outside of a
try / catch
//behavior is the same if you have set a custom error handler
//echo new DateTimeZone(1202229163);
try {
$z = new DateTimeZone(1202229163);
} catch (Exception $e) {
echo "caught exception\n\n";
}
Expected result:
----------------
"caught exception\n\n";
Actual result:
--------------
"user error handler: e_warning=2 num=2
msg=DateTimeZone::__construct(): Unknown or bad timezone
(1202229163) line=15"
--
Edit bug report at http://bugs.php.net/?id=44053&edit=1
--
Try a CVS snapshot (PHP 4.4):
http://bugs.php.net/fix.php?id=44053&r=trysnapshot44
Try a CVS snapshot (PHP 5.2):
http://bugs.php.net/fix.php?id=44053&r=trysnapshot52
Try a CVS snapshot (PHP 5.3):
http://bugs.php.net/fix.php?id=44053&r=trysnapshot53
Try a CVS snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=44053&r=trysnapshot60
Fixed in CVS: http://bugs.php.net/fix.php?id=44053&r=fixedcvs
Fixed in release:
http://bugs.php.net/fix.php?id=44053&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=44053&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=44053&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=44053&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=44053&r=support
Expected behavior: http://bugs.php.net/fix.php?id=44053&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=44053&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=44053&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=44053&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=44053&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=44053&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=44053&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=44053&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=44053&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=44053&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=44053&r=mysqlcfg