Skip to content

Commit ee16316

Browse files
committed
Fixed bug #79948
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.
1 parent 1974522 commit ee16316

File tree

6 files changed

+29
-9
lines changed

6 files changed

+29
-9
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ PHP NEWS
1515
. Fixed bug #79946 (Build fails due to undeclared UINT32_C). (Nikita)
1616
. Fixed bug #77561 (Shebang line not stripped for non-primary script).
1717
(Nikita)
18+
. Fixed bug #79948 (Exit in auto-prepended file does not abort PHP execution).
19+
(Nikita)
1820

1921
- Date:
2022
. Fixed bug #60302 (DateTime::createFromFormat should new static(), not new

Zend/tests/bug79948.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
exit("Exiting...\n");

Zend/tests/bug79948.phpt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Bug #79948: Exit in auto-prepended file does not abort PHP execution
3+
--INI--
4+
auto_prepend_file={PWD}/bug79948.inc
5+
--FILE--
6+
<?php
7+
echo "Should not be executed.\n";
8+
?>
9+
--EXPECT--
10+
Exiting...

Zend/zend.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1674,12 +1674,19 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
16741674
int ret = SUCCESS;
16751675

16761676
va_start(files, file_count);
1677-
for (i = 0; i < file_count && ret != FAILURE; i++) {
1677+
for (i = 0; i < file_count; i++) {
16781678
file_handle = va_arg(files, zend_file_handle *);
16791679
if (!file_handle) {
16801680
continue;
16811681
}
16821682

1683+
if (ret == FAILURE) {
1684+
/* If a failure occurred in one of the earlier files,
1685+
* only destroy the following file handles. */
1686+
zend_file_handle_dtor(file_handle);
1687+
continue;
1688+
}
1689+
16831690
op_array = zend_compile_file(file_handle, type);
16841691
if (file_handle->opened_path) {
16851692
zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path);

Zend/zend_exceptions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -973,8 +973,8 @@ ZEND_API ZEND_COLD int zend_exception_error(zend_object *ex, int severity) /* {{
973973
zend_string_release_ex(str, 0);
974974
zend_string_release_ex(file, 0);
975975
} else if (ce_exception == &zend_ce_unwind_exit) {
976-
/* We successfully unwound, nothing more to do */
977-
result = SUCCESS;
976+
/* We successfully unwound, nothing more to do.
977+
* We still return FAILURE in this case, as further execution should still be aborted. */
978978
} else {
979979
zend_error(severity, "Uncaught exception %s", ZSTR_VAL(ce_exception->name));
980980
}

sapi/cli/php_cli.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -979,9 +979,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
979979
break;
980980
case PHP_MODE_CLI_DIRECT:
981981
cli_register_file_handles();
982-
if (zend_eval_string_ex(exec_direct, NULL, "Command line code", 1) == FAILURE) {
983-
exit_status=254;
984-
}
982+
zend_eval_string_ex(exec_direct, NULL, "Command line code", 1);
983+
exit_status = EG(exit_status);
985984
break;
986985

987986
case PHP_MODE_PROCESS_STDIN:
@@ -993,7 +992,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
993992
cli_register_file_handles();
994993

995994
if (exec_begin && zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1) == FAILURE) {
996-
exit_status=254;
995+
exit_status = EG(exit_status);
997996
}
998997
while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
999998
len = strlen(input);
@@ -1006,7 +1005,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
10061005
zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi);
10071006
if (exec_run) {
10081007
if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) {
1009-
exit_status=254;
1008+
exit_status = EG(exit_status);
10101009
}
10111010
} else {
10121011
if (script_file) {
@@ -1022,7 +1021,7 @@ static int do_cli(int argc, char **argv) /* {{{ */
10221021
efree(input);
10231022
}
10241023
if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) {
1025-
exit_status=254;
1024+
exit_status = EG(exit_status);
10261025
}
10271026

10281027
break;

0 commit comments

Comments
 (0)