Skip to content

Pass zend_string message to zend_error_cb #5639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 25 additions & 19 deletions Zend/zend.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
ZEND_API void (*zend_ticks_function)(int ticks);
ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args);
ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
ZEND_API char *(*zend_getenv)(char *name, size_t name_len);
Expand Down Expand Up @@ -1259,11 +1259,9 @@ ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
} \
} while (0)

static ZEND_COLD void zend_error_va_list(
int orig_type, const char *error_filename, uint32_t error_lineno,
const char *format, va_list args)
static ZEND_COLD void zend_error_impl(
int orig_type, const char *error_filename, uint32_t error_lineno, zend_string *message)
{
va_list usr_copy;
zval params[4];
zval retval;
zval orig_user_error_handler;
Expand Down Expand Up @@ -1308,18 +1306,15 @@ static ZEND_COLD void zend_error_va_list(

#ifdef HAVE_DTRACE
if (DTRACE_ERROR_ENABLED()) {
char *dtrace_error_buffer;
zend_vspprintf(&dtrace_error_buffer, 0, format, args);
DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno);
efree(dtrace_error_buffer);
DTRACE_ERROR(ZSTR_VAL(message), (char *)error_filename, error_lineno);
}
#endif /* HAVE_DTRACE */

/* if we don't have a user defined error handler */
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|| !(EG(user_error_handler_error_reporting) & type)
|| EG(error_handling) != EH_NORMAL) {
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
zend_error_cb(orig_type, error_filename, error_lineno, message);
} else switch (type) {
case E_ERROR:
case E_PARSE:
Expand All @@ -1328,14 +1323,11 @@ static ZEND_COLD void zend_error_va_list(
case E_COMPILE_ERROR:
case E_COMPILE_WARNING:
/* The error may not be safe to handle in user-space */
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
zend_error_cb(orig_type, error_filename, error_lineno, message);
break;
default:
/* Handle the error in user space */
va_copy(usr_copy, args);
ZVAL_STR(&params[1], zend_vstrpprintf(0, format, usr_copy));
va_end(usr_copy);

ZVAL_STR_COPY(&params[1], message);
ZVAL_LONG(&params[0], type);

if (error_filename) {
Expand Down Expand Up @@ -1369,13 +1361,13 @@ static ZEND_COLD void zend_error_va_list(
if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params) == SUCCESS) {
if (Z_TYPE(retval) != IS_UNDEF) {
if (Z_TYPE(retval) == IS_FALSE) {
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
zend_error_cb(orig_type, error_filename, error_lineno, message);
}
zval_ptr_dtor(&retval);
}
} else if (!EG(exception)) {
/* The user error handler failed, use built-in error handler */
zend_error_cb(orig_type, error_filename, error_lineno, format, args);
zend_error_cb(orig_type, error_filename, error_lineno, message);
}

EG(fake_scope) = orig_fake_scope;
Expand Down Expand Up @@ -1411,6 +1403,15 @@ static ZEND_COLD void zend_error_va_list(
}
/* }}} */

static ZEND_COLD void zend_error_va_list(
int orig_type, const char *error_filename, uint32_t error_lineno,
const char *format, va_list args)
{
zend_string *message = zend_vstrpprintf(0, format, args);
zend_error_impl(orig_type, error_filename, error_lineno, message);
zend_string_release(message);
}

static ZEND_COLD void get_filename_lineno(int type, const char **filename, uint32_t *lineno) {
/* Obtain relevant filename and lineno */
switch (type) {
Expand Down Expand Up @@ -1499,7 +1500,6 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(
/* Should never reach this. */
abort();
}
/* }}} */

ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...)
{
Expand All @@ -1514,7 +1514,13 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *
/* Should never reach this. */
abort();
}
/* }}} */

ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) {
const char *filename;
uint32_t lineno;
get_filename_lineno(type, &filename, &lineno);
zend_error_impl(type, filename, lineno, message);
}

ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
{
Expand Down
5 changes: 3 additions & 2 deletions Zend/zend.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ struct _zend_class_entry {
};

typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
void (*error_function)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
size_t (*printf_function)(const char *format, ...) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 1, 2);
size_t (*write_function)(const char *str, size_t str_length);
FILE *(*fopen_function)(const char *filename, zend_string **opened_path);
Expand Down Expand Up @@ -280,7 +280,7 @@ extern ZEND_API zend_write_func_t zend_write;
extern ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path);
extern ZEND_API void (*zend_ticks_function)(int ticks);
extern ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args) ZEND_ATTRIBUTE_PTR_FORMAT(printf, 4, 0);
extern ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
extern ZEND_API void (*zend_on_timeout)(int seconds);
extern ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle);
extern void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
Expand All @@ -300,6 +300,7 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *
/* If filename is NULL the default filename is used. */
ZEND_API ZEND_COLD void zend_error_at(int type, const char *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5);
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn(int type, const char *filename, uint32_t lineno, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 4, 5);
ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message);

ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 1, 2);
Expand Down
37 changes: 18 additions & 19 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ ZEND_API zend_class_entry *zend_get_error_exception(void)
}
/* }}} */

ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code) /* {{{ */
static zend_object *zend_throw_exception_zstr(zend_class_entry *exception_ce, zend_string *message, zend_long code) /* {{{ */
{
zval ex, tmp;

Expand All @@ -836,9 +836,8 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception


if (message) {
ZVAL_STRING(&tmp, message);
ZVAL_STR(&tmp, message);
zend_update_property_ex(exception_ce, &ex, ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
zval_ptr_dtor(&tmp);
}
if (code) {
ZVAL_LONG(&tmp, code);
Expand All @@ -850,6 +849,15 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception
}
/* }}} */

ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception_ce, const char *message, zend_long code) /* {{{ */
{
zend_string *msg_str = zend_string_init(message, strlen(message), 0);
zend_object *ex = zend_throw_exception_zstr(exception_ce, msg_str, code);
zend_string_release(msg_str);
return ex;
}
/* }}} */

ZEND_API ZEND_COLD zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format, ...) /* {{{ */
{
va_list arg;
Expand All @@ -865,10 +873,10 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception_ex(zend_class_entry *except
}
/* }}} */

ZEND_API ZEND_COLD zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, zend_long code, int severity) /* {{{ */
ZEND_API ZEND_COLD zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, zend_string *message, zend_long code, int severity) /* {{{ */
{
zval ex, tmp;
zend_object *obj = zend_throw_exception(exception_ce, message, code);
zend_object *obj = zend_throw_exception_zstr(exception_ce, message, code);
ZVAL_OBJ(&ex, obj);
ZVAL_LONG(&tmp, severity);
zend_update_property_ex(zend_ce_error_exception, &ex, ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp);
Expand All @@ -879,23 +887,14 @@ ZEND_API ZEND_COLD zend_object *zend_throw_error_exception(zend_class_entry *exc
static void zend_error_va(int type, const char *file, uint32_t lineno, const char *format, ...) /* {{{ */
{
va_list args;

va_start(args, format);
zend_error_cb(type, file, lineno, format, args);
zend_string *message = zend_vstrpprintf(0, format, args);
zend_error_cb(type, file, lineno, message);
zend_string_release(message);
va_end(args);
}
/* }}} */

static void zend_error_helper(int type, const char *filename, const uint32_t lineno, const char *format, ...) /* {{{ */
{
va_list va;

va_start(va, format);
zend_error_cb(type, filename, lineno, format, va);
va_end(va);
}
/* }}} */

/* This function doesn't return if it uses E_ERROR */
ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {{{ */
{
Expand All @@ -910,9 +909,9 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));

zend_error_helper(
zend_error_cb(
(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL,
ZSTR_VAL(file), line, "%s", ZSTR_VAL(message));
ZSTR_VAL(file), line, message);

zend_string_release_ex(file, 0);
zend_string_release_ex(message, 0);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception_ex(zend_class_entry *except
ZEND_API ZEND_COLD void zend_throw_exception_object(zval *exception);
ZEND_API void zend_clear_exception(void);

ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, zend_long code, int severity);
ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce, zend_string *message, zend_long code, int severity);

extern ZEND_API void (*zend_throw_exception_hook)(zval *ex);

Expand Down
24 changes: 7 additions & 17 deletions ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ zend_bool fallback_process = 0; /* process uses file cache fallback */
static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type);
static int (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle );
static zend_string *(*accelerator_orig_zend_resolve_path)(const char *filename, size_t filename_len);
static void (*accelerator_orig_zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args);
static void (*accelerator_orig_zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message);
static zif_handler orig_chdir = NULL;
static ZEND_INI_MH((*orig_include_path_on_modify)) = NULL;
static int (*orig_post_startup_cb)(void);
Expand Down Expand Up @@ -1669,37 +1669,27 @@ static void zend_accel_init_auto_globals(void)
}
}

static void persistent_error_cb(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args) {
static void persistent_error_cb(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message) {
if (ZCG(record_warnings)) {
zend_recorded_warning *warning = emalloc(sizeof(zend_recorded_warning));
va_list args_copy;
warning->type = type;
warning->error_lineno = error_lineno;
warning->error_filename = zend_string_init(error_filename, strlen(error_filename), 0);
va_copy(args_copy, args);
warning->error_message = zend_vstrpprintf(0, format, args_copy);
va_end(args_copy);
warning->error_message = zend_string_copy(message);

ZCG(num_warnings)++;
ZCG(warnings) = erealloc(ZCG(warnings), sizeof(zend_recorded_warning) * ZCG(num_warnings));
ZCG(warnings)[ZCG(num_warnings)-1] = warning;
}
accelerator_orig_zend_error_cb(type, error_filename, error_lineno, format, args);
}

/* Hack to get us a va_list to pass to zend_error_cb. */
static void replay_warning_helper(const zend_recorded_warning *warning, ...) {
va_list va;
va_start(va, warning);
accelerator_orig_zend_error_cb(
warning->type, ZSTR_VAL(warning->error_filename), warning->error_lineno, "%s", va);
va_end(va);
accelerator_orig_zend_error_cb(type, error_filename, error_lineno, message);
}

static void replay_warnings(zend_persistent_script *script) {
for (uint32_t i = 0; i < script->num_warnings; i++) {
zend_recorded_warning *warning = script->warnings[i];
replay_warning_helper(warning, ZSTR_VAL(warning->error_message));
accelerator_orig_zend_error_cb(
warning->type, ZSTR_VAL(warning->error_filename), warning->error_lineno,
warning->error_message);
}
}

Expand Down
Loading