diff --git a/Zend/zend.c b/Zend/zend.c index a13884e5516a..311c20d1c4bd 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1858,12 +1858,40 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */ zval_ptr_dtor(&orig_user_exception_handler); } /* }}} */ +ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handle *file_handle) +{ + zend_op_array *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); + } + + zend_result ret = SUCCESS; + if (op_array) { + zend_execute(op_array, retval); + zend_exception_restore(); + if (UNEXPECTED(EG(exception))) { + if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { + zend_user_exception_handler(); + } + if (EG(exception)) { + ret = zend_exception_error(EG(exception), E_ERROR); + } + } + zend_destroy_static_vars(op_array); + destroy_op_array(op_array); + efree_size(op_array, sizeof(zend_op_array)); + } else if (type == ZEND_REQUIRE) { + ret = FAILURE; + } + + return ret; +} + ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */ { va_list files; int i; zend_file_handle *file_handle; - zend_op_array *op_array; zend_result ret = SUCCESS; va_start(files, file_count); @@ -1872,32 +1900,10 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count if (!file_handle) { continue; } - if (ret == FAILURE) { 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); - } - if (op_array) { - zend_execute(op_array, retval); - zend_exception_restore(); - if (UNEXPECTED(EG(exception))) { - if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { - zend_user_exception_handler(); - } - if (EG(exception)) { - ret = zend_exception_error(EG(exception), E_ERROR); - } - } - zend_destroy_static_vars(op_array); - destroy_op_array(op_array); - efree_size(op_array, sizeof(zend_op_array)); - } else if (type==ZEND_REQUIRE) { - ret = FAILURE; - } + ret = zend_execute_script(type, retval, file_handle); } va_end(files); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index ca8e65413292..595bd86dcaca 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -867,6 +867,7 @@ ZEND_API zend_op_array *compile_filename(int type, zend_string *filename); ZEND_API zend_ast *zend_compile_string_to_ast( zend_string *code, struct _zend_arena **ast_arena, zend_string *filename); ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...); +ZEND_API zend_result zend_execute_script(int type, zval *retval, zend_file_handle *file_handle); ZEND_API zend_result open_file_for_scanning(zend_file_handle *file_handle); ZEND_API void init_op_array(zend_op_array *op_array, uint8_t type, int initial_ops_size); ZEND_API void destroy_op_array(zend_op_array *op_array); diff --git a/ext/curl/tests/server.inc b/ext/curl/tests/server.inc index 77df4558d57d..a7b177593db7 100644 --- a/ext/curl/tests/server.inc +++ b/ext/curl/tests/server.inc @@ -71,7 +71,7 @@ function curl_cli_server_start() { } register_shutdown_function( - function($handle) use($router) { + function($handle) { proc_terminate($handle); /* Wait for server to shutdown */ for ($i = 0; $i < 60; $i++) { diff --git a/main/main.c b/main/main.c index b09e9bb99700..29d8642b8f71 100644 --- a/main/main.c +++ b/main/main.c @@ -2431,8 +2431,7 @@ void php_module_shutdown(void) } /* }}} */ -/* {{{ php_execute_script */ -PHPAPI bool php_execute_script(zend_file_handle *primary_file) +PHPAPI bool php_execute_script_ex(zend_file_handle *primary_file, zval *retval) { zend_file_handle *prepend_file_p = NULL, *append_file_p = NULL; zend_file_handle prepend_file, append_file; @@ -2442,7 +2441,7 @@ PHPAPI bool php_execute_script(zend_file_handle *primary_file) char *old_cwd; ALLOCA_FLAG(use_heap) #endif - bool retval = false; + bool result = true; #ifndef HAVE_BROKEN_GETCWD # define OLD_CWD_SIZE 4096 @@ -2501,7 +2500,17 @@ PHPAPI bool php_execute_script(zend_file_handle *primary_file) zend_set_timeout(INI_INT("max_execution_time"), 0); } - retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS); + if (prepend_file_p && result) { + result = zend_execute_script(ZEND_REQUIRE, NULL, prepend_file_p) == SUCCESS; + } + if (result) { + result = zend_execute_script(ZEND_REQUIRE, retval, primary_file) == SUCCESS; + } + if (append_file_p && result) { + result = zend_execute_script(ZEND_REQUIRE, NULL, append_file_p) == SUCCESS; + } + } zend_catch { + result = false; } zend_end_try(); if (prepend_file_p) { @@ -2529,7 +2538,13 @@ PHPAPI bool php_execute_script(zend_file_handle *primary_file) } free_alloca(old_cwd, use_heap); #endif - return retval; + return result; +} + +/* {{{ php_execute_script */ +PHPAPI bool php_execute_script(zend_file_handle *primary_file) +{ + return php_execute_script_ex(primary_file, NULL); } /* }}} */ diff --git a/main/php_main.h b/main/php_main.h index 213043b19b18..1fb460f07f26 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -45,6 +45,7 @@ PHPAPI int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals); PHPAPI zend_result php_register_extensions(zend_module_entry * const * ptr, int count); PHPAPI bool php_execute_script(zend_file_handle *primary_file); +PHPAPI bool php_execute_script_ex(zend_file_handle *primary_file, zval *retval); PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret); PHPAPI zend_result php_lint_script(zend_file_handle *file); diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c index 05110e56a691..4382e8647c31 100644 --- a/sapi/cli/php_cli_server.c +++ b/sapi/cli/php_cli_server.c @@ -2241,20 +2241,13 @@ static bool php_cli_server_dispatch_router(php_cli_server *server, php_cli_serve zend_try { zval retval; - - /* Normally php_execute_script restarts the timer with max_execution_time if it has - * previously been initialized with max_input_time. We're not using php_execute_script here - * because it does not provide a way to get the return value of the main script, so we need - * to restart the timer manually. */ - if (PG(max_input_time) != -1) { -#ifdef PHP_WIN32 - zend_unset_timeout(); -#endif - zend_set_timeout(INI_INT("max_execution_time"), 0); - } - ZVAL_UNDEF(&retval); - if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE, &retval, 1, &zfd)) { + int sg_options_back = SG(options); + /* Don't chdir to the router script because the file path may be relative. */ + SG(options) |= SAPI_OPTION_NO_CHDIR; + bool result = php_execute_script_ex(&zfd, &retval); + SG(options) = sg_options_back; + if (result) { if (Z_TYPE(retval) != IS_UNDEF) { decline = Z_TYPE(retval) == IS_FALSE; zval_ptr_dtor(&retval); diff --git a/sapi/cli/tests/gh13113.phpt b/sapi/cli/tests/gh13113.phpt new file mode 100644 index 000000000000..5638bdf450d4 --- /dev/null +++ b/sapi/cli/tests/gh13113.phpt @@ -0,0 +1,38 @@ +--TEST-- +GH-13113: Missing syntax error in CLI-server router script +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 200 OK +Host: %s +Date: %s +Connection: close +X-Powered-By: PHP/%s +Content-type: text/html; charset=UTF-8 + +
+Parse error: syntax error, unexpected identifier "bar" in %sindex.php on line 1