php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78489 "php -a" will terminate immediately for any thrown CompileError
Submitted: 2019-09-04 01:40 UTC Modified: -
From: tandre@php.net Assigned:
Status: Open Package: *General Issues
PHP Version: 7.3.9 OS:
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: tandre@php.net
New email:
PHP Version: OS:

 

 [2019-09-04 01:40 UTC] 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)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-09-04 01:48 UTC] tandre@php.net
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;
				}
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 15:01:32 2024 UTC