Fix GH-13097: Anonymous class reference in trigger_error / thrown Exception

Closes GH-13153.
This commit is contained in:
Niels Dossche 2024-01-15 20:21:30 +01:00
parent 9814d4a191
commit 2cde4b2ea4
6 changed files with 49 additions and 8 deletions

2
NEWS
View File

@ -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)

15
Zend/tests/gh13097_a.phpt Normal file
View File

@ -0,0 +1,15 @@
--TEST--
GH-13097 (Anonymous class reference in trigger_error / thrown Exception)
--FILE--
<?php
$anonymous = new class(){};
trigger_error(
get_class($anonymous).' ...now you don\'t!',
E_USER_ERROR
);
?>
--EXPECTF--
Fatal error: class@anonymous%s ...now you don't! in %s on line %d

18
Zend/tests/gh13097_b.phpt Normal file
View File

@ -0,0 +1,18 @@
--TEST--
GH-13097 (Anonymous class reference in trigger_error / thrown Exception)
--FILE--
<?php
$anonymous = new class(){};
throw new Exception(
get_class($anonymous).' ...now you don\'t!',
E_USER_ERROR
);
?>
--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

View File

@ -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;
}

View File

@ -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);

View File

@ -1350,19 +1350,25 @@ static ZEND_COLD void php_error_cb(int orig_type, zend_string *error_filename, c
php_printf("%s<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%" PRIu32 "</b><br />\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<br />\n<b>%s</b>: %s in <b>%s</b> on line <b>%" PRIu32 "</b><br />\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<br />\n<b>%s</b>: %Z in <b>%s</b> on line <b>%" PRIu32 "</b><br />\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));
}
}
}