php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #44053 Core exceptions are actually E_WARNINGs first
Submitted: 2008-02-05 19:33 UTC Modified: 2008-02-24 19:59 UTC
Votes:4
Avg. Score:3.8 ± 0.4
Reproduced:3 of 3 (100.0%)
Same Version:1 (33.3%)
Same OS:2 (66.7%)
From: mark at metrofindings dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 5.2.5 OS: linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: mark at metrofindings dot com
New email:
PHP Version: OS:

 

 [2008-02-05 19:33 UTC] mark at metrofindings dot com
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"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-02-05 19:41 UTC] mark at metrofindings dot com
Although, at first glace, this bug appears to be the same as 43377 
(http://bugs.php.net/bug.php?id=43377), it is not.  Bug 43377 is 
referring to a crash and was later reopened because all exceptions 
are caught be the user defined error handler.  I feel that the core 
problem is not reflected clearly enough in 43377 and it warrants a 
new bug since the original problem of that bug was fixed.
 [2008-02-24 19:59 UTC] jani@php.net
Duplicate of (open) bug #43377 so bogus.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sun Feb 02 22:01:30 2025 UTC