Skip to content

Commit 43a579e

Browse files
author
Patrick Allaert
committed
Make it possible to break error hook processing
Error hooks should normally return SUCCESS but they can return FAILURE in order to stop the processing of the current hook list as it is the case for the bailout one. It also has the benefit of standardizing the API for error hooks.
1 parent 0b44966 commit 43a579e

File tree

3 files changed

+20
-26
lines changed

3 files changed

+20
-26
lines changed

Zend/zend_errors.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "ext/standard/html.h"
2727

2828
/* {{{ zend_error_display_cb */
29-
ZEND_API void zend_error_display_cb(ZEND_ERROR_CB_HOOK_ARGS)
29+
ZEND_ERROR_CB_API zend_error_display_cb(ZEND_ERROR_CB_HOOK_ARGS)
3030
{
3131
char *buffer = PG(last_error_message);
3232

@@ -80,11 +80,12 @@ ZEND_API void zend_error_display_cb(ZEND_ERROR_CB_HOOK_ARGS)
8080
zend_output_debug_string(trigger_break, "%s(%d) : %s - %s", error_filename, error_lineno, error_type_str, buffer);
8181
}
8282
#endif
83+
return SUCCESS;
8384
}
8485
/* }}} */
8586

8687
/* {{{ zend_error_log_cb */
87-
ZEND_API void zend_error_log_cb(ZEND_ERROR_CB_HOOK_ARGS)
88+
ZEND_ERROR_CB_API zend_error_log_cb(ZEND_ERROR_CB_HOOK_ARGS)
8889
{
8990
char *buffer = PG(last_error_message);
9091

@@ -99,11 +100,12 @@ ZEND_API void zend_error_log_cb(ZEND_ERROR_CB_HOOK_ARGS)
99100
php_log_err(log_buffer);
100101
efree(log_buffer);
101102
}
103+
return SUCCESS;
102104
}
103105
/* }}} */
104106

105107
/* {{{ zend_error_bailout_cb */
106-
ZEND_API zend_bool zend_error_bailout_cb(ZEND_ERROR_CB_HOOK_ARGS)
108+
ZEND_ERROR_CB_API zend_error_bailout_cb(ZEND_ERROR_CB_HOOK_ARGS)
107109
{
108110
/* Bail out if we can't recover */
109111
switch (type) {
@@ -138,11 +140,11 @@ ZEND_API zend_bool zend_error_bailout_cb(ZEND_ERROR_CB_HOOK_ARGS)
138140
zend_set_memory_limit(PG(memory_limit));
139141
zend_objects_store_mark_destructed(&EG(objects_store));
140142
zend_bailout();
141-
return 1;
143+
return FAILURE;
142144
}
143145
}
144146
}
145-
return 0;
147+
return SUCCESS;
146148
}
147149
/* }}} */
148150

Zend/zend_errors.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ typedef enum {
5656
#define ZEND_ERROR_CB_FUNC_ARGS_PASSTHRU type, error_filename, error_lineno, format, args
5757
#define ZEND_ERROR_CB_HOOK_ARGS ZEND_ERROR_CB_FUNC_ARGS, const char *error_type_str
5858
#define ZEND_ERROR_CB_HOOK_ARGS_PASSTHRU ZEND_ERROR_CB_FUNC_ARGS_PASSTHRU, error_type_str
59+
#define ZEND_ERROR_CB_API ZEND_API int
5960

6061
BEGIN_EXTERN_C()
61-
ZEND_API void zend_error_display_cb(ZEND_ERROR_CB_HOOK_ARGS);
62-
ZEND_API void zend_error_log_cb(ZEND_ERROR_CB_HOOK_ARGS);
63-
ZEND_API zend_bool zend_error_bailout_cb(ZEND_ERROR_CB_HOOK_ARGS);
62+
ZEND_ERROR_CB_API zend_error_display_cb(ZEND_ERROR_CB_HOOK_ARGS);
63+
ZEND_ERROR_CB_API zend_error_log_cb(ZEND_ERROR_CB_HOOK_ARGS);
64+
ZEND_ERROR_CB_API zend_error_bailout_cb(ZEND_ERROR_CB_HOOK_ARGS);
6465
ZEND_API void zend_append_error_hook(zend_error_cb_hook_t hook_part, void (*hook)(ZEND_ERROR_CB_HOOK_ARGS));
6566
ZEND_API void zend_prepend_error_hook(zend_error_cb_hook_t hook_part, void (*hook)(ZEND_ERROR_CB_HOOK_ARGS));
6667
ZEND_API void zend_clear_error_hook(zend_error_cb_hook_t hook_part);

main/main.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -961,11 +961,12 @@ PHPAPI void php_html_puts(const char *str, size_t size)
961961
/* }}} */
962962

963963
#define CALL_ERROR_HOOKS(HOOK_LIST) for ( \
964-
hook = (void (**)(ZEND_ERROR_CB_HOOK_ARGS)) zend_llist_get_first_ex(&(PG(error_hooks)[HOOK_LIST]), &pos); \
965-
hook != NULL; \
964+
hook_result = SUCCESS, \
965+
hook = (int (**)(ZEND_ERROR_CB_HOOK_ARGS)) zend_llist_get_first_ex(&(PG(error_hooks)[HOOK_LIST]), &pos); \
966+
hook != NULL && hook_result == SUCCESS; \
966967
hook = zend_llist_get_next_ex(&(PG(error_hooks)[HOOK_LIST]), &pos)) { \
967968
va_copy(copy, args); \
968-
(*hook)(type, error_filename, error_lineno, format, copy, error_type_str); \
969+
hook_result = (*hook)(type, error_filename, error_lineno, format, copy, error_type_str); \
969970
va_end(copy); \
970971
}
971972

@@ -976,10 +977,9 @@ static void php_error_cb(PHP_ERROR_CB_FUNC_ARGS)
976977
char *buffer, *error_type_str;
977978
int buffer_len, display;
978979
zend_llist_position pos;
979-
void (**hook)(ZEND_ERROR_CB_HOOK_ARGS);
980-
zend_bool (**bailout_hook)(ZEND_ERROR_CB_HOOK_ARGS);
980+
int (**hook)(ZEND_ERROR_CB_HOOK_ARGS);
981981
va_list copy;
982-
zend_bool bailout = 0;
982+
int hook_result;
983983

984984
buffer_len = (int)vspprintf(&buffer, PG(log_errors_max_len), format, args);
985985

@@ -1097,19 +1097,10 @@ static void php_error_cb(PHP_ERROR_CB_FUNC_ARGS)
10971097
CALL_ERROR_HOOKS(E_HOOK_PROCESS);
10981098
}
10991099

1100-
for (
1101-
bailout_hook = (zend_bool (**)(ZEND_ERROR_CB_HOOK_ARGS)) zend_llist_get_first_ex(&(PG(error_hooks)[E_HOOK_BAILOUT]), &pos);
1102-
bailout_hook != NULL;
1103-
bailout_hook = zend_llist_get_next_ex(&(PG(error_hooks)[E_HOOK_BAILOUT]), &pos)) {
1104-
va_copy(copy, args);
1105-
bailout = (*bailout_hook)(type, error_filename, error_lineno, format, copy, error_type_str);
1106-
va_end(copy);
1107-
if (bailout) {
1108-
goto error_cb_end;
1109-
}
1110-
}
1100+
CALL_ERROR_HOOKS(E_HOOK_BAILOUT);
11111101

1112-
if (!display) {
1102+
// hook_result == FAILURE means we must bail out
1103+
if (hook_result == FAILURE || !display) {
11131104
goto error_cb_end;
11141105
}
11151106

0 commit comments

Comments
 (0)