]> granicus.if.org Git - php/commitdiff
Fixed bug #79948
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 08:28:13 +0000 (10:28 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 09:15:16 +0000 (11:15 +0200)
Make sure we don't execute further scripts if one of them encountered
an exit exception.

Also make sure that we free file handles that end up unused due to
an early abort in php_execute_scripts(), which turned up as an
issue in the added test case.

Finally, make use of EG(exit_status) in the places where we
zend_eval_string_ex, instead of unconditionally assigning exit
code 254. If an error occurs, the error handler will already set
exit status 255.

NEWS
Zend/tests/bug79948.inc [new file with mode: 0644]
Zend/tests/bug79948.phpt [new file with mode: 0644]
Zend/zend.c
Zend/zend_exceptions.c
sapi/cli/php_cli.c

diff --git a/NEWS b/NEWS
index 0ed3122f90f63e658c51089a22980e6968da3563..b8d4bd06439191343d915d715e83b62009140f0a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,8 @@ PHP                                                                        NEWS
   . Fixed bug #79946 (Build fails due to undeclared UINT32_C). (Nikita)
   . Fixed bug #77561 (Shebang line not stripped for non-primary script).
     (Nikita)
+  . Fixed bug #79948 (Exit in auto-prepended file does not abort PHP execution).
+    (Nikita)
 
 - Date:
   . Fixed bug #60302 (DateTime::createFromFormat should new static(), not new
diff --git a/Zend/tests/bug79948.inc b/Zend/tests/bug79948.inc
new file mode 100644 (file)
index 0000000..b112b43
--- /dev/null
@@ -0,0 +1,2 @@
+<?php
+exit("Exiting...\n");
diff --git a/Zend/tests/bug79948.phpt b/Zend/tests/bug79948.phpt
new file mode 100644 (file)
index 0000000..777a926
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Bug #79948: Exit in auto-prepended file does not abort PHP execution
+--INI--
+auto_prepend_file={PWD}/bug79948.inc
+--FILE--
+<?php
+echo "Should not be executed.\n";
+?>
+--EXPECT--
+Exiting...
index 4b001c522cca826a75a42cf9df4a716ebf15c9c6..2aa37b0536acc4970f29262ace4a2686ecbe5926 100644 (file)
@@ -1674,12 +1674,19 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
        int ret = SUCCESS;
 
        va_start(files, file_count);
-       for (i = 0; i < file_count && ret != FAILURE; i++) {
+       for (i = 0; i < file_count; i++) {
                file_handle = va_arg(files, zend_file_handle *);
                if (!file_handle) {
                        continue;
                }
 
+               if (ret == FAILURE) {
+                       /* If a failure occurred in one of the earlier files,
+                        * only destroy the following file handles. */
+                       zend_file_handle_dtor(file_handle);
+                       continue;
+               }
+
                op_array = zend_compile_file(file_handle, type);
                if (file_handle->opened_path) {
                        zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);
index de95b2a8c0965dc274be77fa2dbc7054d252cdec..2923165e566514f39606a8c14e848297a33ee93f 100644 (file)
@@ -973,8 +973,8 @@ ZEND_API ZEND_COLD int zend_exception_error(zend_object *ex, int severity) /* {{
                zend_string_release_ex(str, 0);
                zend_string_release_ex(file, 0);
        } else if (ce_exception == &zend_ce_unwind_exit) {
-               /* We successfully unwound, nothing more to do */
-               result = SUCCESS;
+               /* We successfully unwound, nothing more to do.
+                * We still return FAILURE in this case, as further execution should still be aborted. */
        } else {
                zend_error(severity, "Uncaught exception %s", ZSTR_VAL(ce_exception->name));
        }
index 4874e0920cebeef15c8a55c1cc85b43fb4286061..81bad21ae67c3f935e68d328cd3e525ca0c05035 100644 (file)
@@ -979,9 +979,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
                        break;
                case PHP_MODE_CLI_DIRECT:
                        cli_register_file_handles();
-                       if (zend_eval_string_ex(exec_direct, NULL, "Command line code", 1) == FAILURE) {
-                               exit_status=254;
-                       }
+                       zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
+                       exit_status = EG(exit_status);
                        break;
 
                case PHP_MODE_PROCESS_STDIN:
@@ -993,7 +992,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                cli_register_file_handles();
 
                                if (exec_begin && zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1) == FAILURE) {
-                                       exit_status=254;
+                                       exit_status = EG(exit_status);
                                }
                                while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
                                        len = strlen(input);
@@ -1006,7 +1005,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                        zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi);
                                        if (exec_run) {
                                                if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) {
-                                                       exit_status=254;
+                                                       exit_status = EG(exit_status);
                                                }
                                        } else {
                                                if (script_file) {
@@ -1022,7 +1021,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                        efree(input);
                                }
                                if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) {
-                                       exit_status=254;
+                                       exit_status = EG(exit_status);
                                }
 
                                break;