Bug #78489 [Com]: "php -a" will terminate immediately for any thrown CompileError
| From: | tandre@php.net | Date: | Wed, 04 Sep 2019 01:48:52 +0000 |
| Subject: | Bug #78489 [Com]: "php -a" will terminate immediately for any thrown CompileError | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222546@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78489&edit=1
ID: 78489
Comment by: tandre@php.net
Reported by: tandre@php.net
Summary: "php -a" will terminate immediately for any thrown
CompileError
Status: Open
Type: Bug
Package: *General Issues
PHP Version: 7.3.9
Block user comment: N
Private report: N
New Comment:
Just noticed on https://github.com/php/php-src/pull/2767#issue-142753913
> Additionally reusing the ParseError class for this purpose would change existing error messages
> (if the exception is not caught) from a "Fatal error:" to a "Parse error:"
> prefix, and also the error kind from E_COMPILE_ERROR to E_PARSE.
Keeping "Fatal error" (or making it "Recoverable fatal error" if in a different
file?) might make sense for SAPIs other than the one used for "php -a".
This block of
php_error_cb looks like the reason why php -a bails out unless the error
type is E_PARSE (not E_COMPILE_ERROR)
/* the parser would return 1 (failure), we can bail out nicely */
if (type != E_PARSE) {
/* restore memory limit */
zend_set_memory_limit(PG(memory_limit));
efree(buffer);
zend_objects_store_mark_destructed(&EG(objects_store));
zend_bailout();
return;
}
Previous Comments:
------------------------------------------------------------------------
[2019-09-04 01:40:04] tandre@php.net
Description:
------------
Observed: "php -a" terminates immediately when CompileError is thrown and not caught, but
does not terminate for any thrown subclass (e.g. ParseError)
Expected: "php -a" should report the error appropriately, but not terminate
Cause: https://github.com/php/php-src/pull/2767#discussion_r320539776
// in main/main.c, we see that E_COMPILE_ERROR is treated differently from E_PARSE, and
zend_ce_compile_error causes E_COMPILE_ERROR.
// Changing main.c to check if E_COMPILE_ERROR is recoverable would fix the bug.
case E_ERROR:
case E_CORE_ERROR:
case E_COMPILE_ERROR:
case E_USER_ERROR:
error_type_str = "Fatal error";
syslog_type_int = LOG_ERR;
break;
Test script:
---------------
php > throw new ParseError('x');
Parse error: x in php shell code on line 1
php > throw new CompileError('x');
Fatal error: x in php shell code on line 1
.... This terminates php -a
php > var_export(token_get_all('<?php abstract final class X{}', TOKEN_PARSE));
Fatal error: Cannot use the final modifier on an abstract class in on line 1
.... This also terminates php -a
php > try {throw new CompileError('x');} catch (Throwable $_) { var_export($_); }
Outputs CompileError::__set_state(array(...
Expected result:
----------------
"php -a" should report the error appropriately, but not terminate
Actual result:
--------------
Observed: "php -a" terminates immediately when CompileError is thrown and not caught, but
does not terminate for any thrown subclass (e.g. ParseError)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78489&edit=1