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