php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #78537 Make it possible to handle E_COMPILE_WARNING in set_error_handler
Submitted: 2019-09-14 17:03 UTC Modified: 2019-09-30 08:57 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: tandre@php.net Assigned: nikic (profile)
Status: Assigned Package: *General Issues
PHP Version: Irrelevant OS: All
Private report: No CVE-ID: None
 [2019-09-14 17:03 UTC] tandre@php.net
Description:
------------
https://www.php.net/set_error_handler

> The following error types cannot be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.

This is inconvenient for the following reasons:
- Compile warnings unintuitively can't be reported using whatever monitoring was set up in set_error_handler, and may go unnoticed because of this.
- Static analyzers (etc.) don't have a way to fetch the full list of E_COMPILE_WARNINGS if there was more than one warning. Warnings such as invalid octal escapes can occur more than once.

This also seems like a distinction that may no longer be necessary.

- This was implemented in 2000 in https://github.com/php/php-src/commit/b80b8381d4c#diff-b09edfedd835ebc4491e565c147190e7R559 . The php engine has had many improvements (class Error), and this change may no longer be necessary
- PHP tokenization(Zend/zend_language_scanner.l) can emit both E_COMPILE_WARNING (e.g. "Unterminated comment starting line %d") and E_DEPRECATED ("The (real) cast is deprecated, use (float) instead"). The latter can be handled by user error handlers.

I see that https://bugs.php.net/bug.php?id=52517 was reported for php 5.3, but I still think this should be revisited for the following reasons.

- E_DEPRECATED and E_COMPILE_WARNING can both be emitted when tokenizing
- We may want to reconsider emitting E_DEPRECATED in php 7.4 for curly braces/real casts if php-src should truly never throw without evaluating the include()d file. (a user error handler could throw)
- The improvements to the php engine since php 5.3 were significant and may allow user error handlers to be safely called. (finally{}, class Error, etc)
- I couldn't find any pre-existing discussion of this for php 7

Test script:
---------------
<?php
// The only warning using E_DEPRECATED was introduced in php 7.4
if (PHP_VERSION_ID < 70400) { throw new Error('Expected php 7.4+'); }
set_error_handler(function ($errno, $errstr) {
    echo "In custom error handler: $errno $errstr\n";
});
// Warning: Unterminated comment starting line 1 in /home/tyson/programming/php-src/test.php(6) : eval()'d code on line 1
// Evaluated 1
eval('echo "Evaluated 1\n";/** ');
// In custom error handler: 8192 Array and string offset access syntax with curly braces is deprecated
// Evaluated 2
eval('echo "Evaluated 2\n";if (false) {$x{2} = 3;}');



Expected result:
----------------
The "Unterminated comment starting line 1" warning would be handled by the custom error handler

Actual result:
--------------
The "Unterminated comment starting line 1" is printed to stderr and cannot be handled

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-09-30 08:57 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC