]> granicus.if.org Git - php/commitdiff
Fixed bug #65275
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 10:39:19 +0000 (12:39 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 10:40:26 +0000 (12:40 +0200)
Make EG(exit_status) the single source of truth for the exit status,
instead of having two variables that we cannot really keep
synchronized.

NEWS
main/main.c
sapi/cli/php_cli.c
sapi/cli/tests/bug65275.inc [new file with mode: 0644]
sapi/cli/tests/bug65275.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b8d4bd06439191343d915d715e83b62009140f0a..93a8ecbb93f4ad32ab63e7352938097cc0f68bc1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ PHP                                                                        NEWS
     (Nikita)
   . Fixed bug #79948 (Exit in auto-prepended file does not abort PHP execution).
     (Nikita)
+  . Fixed bug #65275 (Calling exit() in a shutdown function does not change the
+    exit value in CLI). (Nikita)
 
 - Date:
   . Fixed bug #60302 (DateTime::createFromFormat should new static(), not new
index 390b08c4aa91c029d8a635a3695172b2e668d1d5..9e0d4ba8822f6168a7ed07782fe9ba258bd7c34c 100644 (file)
@@ -2471,7 +2471,6 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file)
 #endif
        int retval = 0;
 
-       EG(exit_status) = 0;
 #ifndef HAVE_BROKEN_GETCWD
 # define OLD_CWD_SIZE 4096
        old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
index 81bad21ae67c3f935e68d328cd3e525ca0c05035..34bf1aee38765e8007fb961f8d329a59368791c0 100644 (file)
@@ -607,7 +607,6 @@ static int do_cli(int argc, char **argv) /* {{{ */
        int behavior = PHP_MODE_STANDARD;
        char *reflection_what = NULL;
        volatile int request_started = 0;
-       volatile int exit_status = 0;
        char *php_optarg = NULL, *orig_optarg = NULL;
        int php_optind = 1, orig_optind = 1;
        char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL;
@@ -631,7 +630,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                request_started = 1;
                                php_print_info(0xFFFFFFFF);
                                php_output_end_all();
-                               exit_status = (c == '?' && argc > 1 && !strchr(argv[1],  c));
+                               EG(exit_status) = (c == '?' && argc > 1 && !strchr(argv[1],  c));
                                goto out;
 
                        case 'v': /* show php version & quit */
@@ -673,7 +672,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                print_extensions();
                                php_printf("\n");
                                php_output_end_all();
-                               exit_status=0;
+                               EG(exit_status) = 0;
                                goto out;
 
                        default:
@@ -848,7 +847,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
 
                if (param_error) {
                        PUTS(param_error);
-                       exit_status=1;
+                       EG(exit_status) = 1;
                        goto err;
                }
 
@@ -946,15 +945,14 @@ static int do_cli(int argc, char **argv) /* {{{ */
                        }
 
                        if (interactive && cli_shell_callbacks.cli_shell_run) {
-                               exit_status = cli_shell_callbacks.cli_shell_run();
+                               EG(exit_status) = cli_shell_callbacks.cli_shell_run();
                        } else {
                                php_execute_script(&file_handle);
-                               exit_status = EG(exit_status);
                        }
                        break;
                case PHP_MODE_LINT:
-                       exit_status = php_lint_script(&file_handle);
-                       if (exit_status==SUCCESS) {
+                       EG(exit_status) = php_lint_script(&file_handle);
+                       if (EG(exit_status) == SUCCESS) {
                                zend_printf("No syntax errors detected in %s\n", file_handle.filename);
                        } else {
                                zend_printf("Errors parsing %s\n", file_handle.filename);
@@ -980,7 +978,6 @@ static int do_cli(int argc, char **argv) /* {{{ */
                case PHP_MODE_CLI_DIRECT:
                        cli_register_file_handles();
                        zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
-                       exit_status = EG(exit_status);
                        break;
 
                case PHP_MODE_PROCESS_STDIN:
@@ -991,10 +988,10 @@ 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 = EG(exit_status);
+                               if (exec_begin) {
+                                       zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1);
                                }
-                               while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
+                               while (EG(exit_status) == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
                                        len = strlen(input);
                                        while (len > 0 && len-- && (input[len]=='\n' || input[len]=='\r')) {
                                                input[len] = '\0';
@@ -1004,24 +1001,21 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                        ZVAL_LONG(&argi, ++index);
                                        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 = EG(exit_status);
-                                               }
+                                               zend_eval_string_ex(exec_run, NULL, "Command line run code", 1);
                                        } else {
                                                if (script_file) {
                                                        if (cli_seek_file_begin(&file_handle, script_file) != SUCCESS) {
-                                                               exit_status = 1;
+                                                               EG(exit_status) = 1;
                                                        } else {
                                                                CG(skip_shebang) = 1;
                                                                php_execute_script(&file_handle);
-                                                               exit_status = EG(exit_status);
                                                        }
                                                }
                                        }
                                        efree(input);
                                }
-                               if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) {
-                                       exit_status = EG(exit_status);
+                               if (exec_end) {
+                                       zend_eval_string_ex(exec_end, NULL, "Command line end code", 1);
                                }
 
                                break;
@@ -1091,7 +1085,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                                        display_ini_entries(NULL);
                                                } else {
                                                        zend_printf("Extension '%s' not present.\n", reflection_what);
-                                                       exit_status = 1;
+                                                       EG(exit_status) = 1;
                                                }
                                        } else {
                                                php_info_print_module(module);
@@ -1119,14 +1113,11 @@ out:
        if (translated_path) {
                free(translated_path);
        }
-       if (exit_status == 0) {
-               exit_status = EG(exit_status);
-       }
-       return exit_status;
+       return EG(exit_status);
 err:
        sapi_deactivate();
        zend_ini_deactivate();
-       exit_status = 1;
+       EG(exit_status) = 1;
        goto out;
 }
 /* }}} */
diff --git a/sapi/cli/tests/bug65275.inc b/sapi/cli/tests/bug65275.inc
new file mode 100644 (file)
index 0000000..6b8a2ad
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+
+register_shutdown_function(function() {
+       die(111);
+});
+
+die(222);
diff --git a/sapi/cli/tests/bug65275.phpt b/sapi/cli/tests/bug65275.phpt
new file mode 100644 (file)
index 0000000..1d59515
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+Bug #65275: Calling exit() in a shutdown function does not change the exit value in CLI
+--FILE--
+<?php
+
+$php = getenv('TEST_PHP_EXECUTABLE');
+exec($php . ' ' . __DIR__ . '/bug65275.inc', $output, $exit_status);
+var_dump($exit_status);
+
+?>
+--EXPECT--
+int(111)