From 2cde4b2ea46129f7a11ac6c6234dd4691e05a8f3 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Mon, 15 Jan 2024 20:21:30 +0100 Subject: [PATCH] Fix GH-13097: Anonymous class reference in trigger_error / thrown Exception Closes GH-13153. --- NEWS | 2 ++ Zend/tests/gh13097_a.phpt | 15 +++++++++++++++ Zend/tests/gh13097_b.phpt | 18 ++++++++++++++++++ Zend/zend_builtin_functions.c | 7 +++---- Zend/zend_exceptions.c | 3 ++- main/main.c | 12 +++++++++--- 6 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 Zend/tests/gh13097_a.phpt create mode 100644 Zend/tests/gh13097_b.phpt diff --git a/NEWS b/NEWS index c826604c07f..5509955c51c 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Fixed timer leak in zend-max-execution-timers builds. (withinboredom) . Fixed bug GH-12349 (linking failure on ARM with mold). (Jan Palus) + . Fixed bug GH-13097 (Anonymous class reference in trigger_error / thrown + Exception). (nielsdos) - Curl: . Fix missing error check in curl_multi_init(). (divinity76) diff --git a/Zend/tests/gh13097_a.phpt b/Zend/tests/gh13097_a.phpt new file mode 100644 index 00000000000..b9ad729f66e --- /dev/null +++ b/Zend/tests/gh13097_a.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-13097 (Anonymous class reference in trigger_error / thrown Exception) +--FILE-- + +--EXPECTF-- +Fatal error: class@anonymous%s ...now you don't! in %s on line %d diff --git a/Zend/tests/gh13097_b.phpt b/Zend/tests/gh13097_b.phpt new file mode 100644 index 00000000000..7473c99d9f4 --- /dev/null +++ b/Zend/tests/gh13097_b.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-13097 (Anonymous class reference in trigger_error / thrown Exception) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Exception: class@anonymous%s ...now you don't! in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 9c4b836cafa..72cb07decbd 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1108,10 +1108,9 @@ ZEND_FUNCTION(get_included_files) ZEND_FUNCTION(trigger_error) { zend_long error_type = E_USER_NOTICE; - char *message; - size_t message_len; + zend_string *message; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &message, &message_len, &error_type) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &message, &error_type) == FAILURE) { RETURN_THROWS(); } @@ -1128,7 +1127,7 @@ ZEND_FUNCTION(trigger_error) break; } - zend_error((int)error_type, "%s", message); + zend_error_zstr_at(error_type, zend_get_executed_filename_ex(), zend_get_executed_lineno(), message); // TODO Change to void RETURN_TRUE; } diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 2b2f6dfb4b3..8ad603e51e7 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -950,9 +950,10 @@ ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *ex, int severit file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE)); line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE)); + ZVAL_STR(&tmp, str); zend_error_va(severity | E_DONT_BAIL, (file && ZSTR_LEN(file) > 0) ? file : NULL, line, - "Uncaught %s\n thrown", ZSTR_VAL(str)); + "Uncaught %Z\n thrown", &tmp); zend_string_release_ex(str, 0); zend_string_release_ex(file, 0); diff --git a/main/main.c b/main/main.c index b2d03b4af8a..83f8829890e 100644 --- a/main/main.c +++ b/main/main.c @@ -1350,19 +1350,25 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c php_printf("%s
\n%s: %s in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(buf), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); zend_string_free(buf); } else { - php_printf("%s
\n%s: %s in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); + zval tmp; + ZVAL_STR(&tmp, message); + php_printf_unchecked("%s
\n%s: %Z in %s on line %" PRIu32 "
\n%s", STR_PRINT(prepend_string), error_type_str, &tmp, ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); } } else { /* Write CLI/CGI errors to stderr if display_errors = "stderr" */ if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi") || !strcmp(sapi_module.name, "phpdbg")) && PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR ) { - fprintf(stderr, "%s: %s in %s on line %" PRIu32 "\n", error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno); + fprintf(stderr, "%s: ", error_type_str); + fwrite(ZSTR_VAL(message), sizeof(char), ZSTR_LEN(message), stderr); + fprintf(stderr, " in %s on line %" PRIu32 "\n", ZSTR_VAL(error_filename), error_lineno); #ifdef PHP_WIN32 fflush(stderr); #endif } else { - php_printf("%s\n%s: %s in %s on line %" PRIu32 "\n%s", STR_PRINT(prepend_string), error_type_str, ZSTR_VAL(message), ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); + zval tmp; + ZVAL_STR(&tmp, message); + php_printf_unchecked("%s\n%s: %Z in %s on line %" PRIu32 "\n%s", STR_PRINT(prepend_string), error_type_str, &tmp, ZSTR_VAL(error_filename), error_lineno, STR_PRINT(append_string)); } } }