mirror of
https://github.com/php/php-src.git
synced 2026-03-26 01:02:25 +01:00
- Turns out the easy solution for correct error_handling doesn't work. So
we need to provide save/replace/restore functions right away. It also to save/restore in the vm.
This commit is contained in:
@@ -802,6 +802,15 @@ typedef enum {
|
||||
EH_THROW
|
||||
} zend_error_handling_t;
|
||||
|
||||
typedef struct {
|
||||
zend_error_handling_t handling;
|
||||
zend_class_entry *exception;
|
||||
} zend_error_handling;
|
||||
|
||||
ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC);
|
||||
ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current TSRMLS_DC);
|
||||
ZEND_API void zend_restore_error_handling(const zend_error_handling *saved TSRMLS_DC);
|
||||
|
||||
#define ZEND_U_EQUAL(type, ustr, ulen, str, slen) \
|
||||
((type == IS_STRING)? \
|
||||
(!memcmp((ustr).s,(str),(slen))): \
|
||||
|
||||
@@ -4285,6 +4285,37 @@ ZEND_API zend_uchar zend_get_unified_string_type(int num_args TSRMLS_DC, ...) /*
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_save_error_handling(zend_error_handling *current TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
current->handling = EG(error_handling);
|
||||
current->exception = EG(exception_class);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (current) {
|
||||
zend_save_error_handling(current TSRMLS_CC);
|
||||
}
|
||||
EG(error_handling) = error_handling;
|
||||
EG(exception_class) = error_handling == EH_THROW ? exception_class : NULL;
|
||||
|
||||
if (error_handling == EH_NORMAL) {
|
||||
EG(user_error_handler) = EG(user_error_handler_old);
|
||||
} else {
|
||||
EG(user_error_handler_old) = EG(user_error_handler);
|
||||
EG(user_error_handler) = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_restore_error_handling(const zend_error_handling *saved TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
EG(error_handling) = saved->handling;
|
||||
EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
||||
@@ -947,16 +947,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
EG(opline_ptr) = original_opline_ptr;
|
||||
} else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
|
||||
zend_error_handling_t error_handling = EG(error_handling);
|
||||
zend_class_entry *exception_class = EG(exception_class);
|
||||
|
||||
zend_error_handling error_handling;
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
|
||||
if (EX(function_state).function->common.scope) {
|
||||
EG(scope) = EX(function_state).function->common.scope;
|
||||
}
|
||||
((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
|
||||
EG(error_handling) = error_handling;
|
||||
EG(exception_class) = exception_class;
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
/* We shouldn't fix bad extensions here,
|
||||
because it can break proper ones (Bug #34045)
|
||||
if (!EX(function_state).function->common.return_reference)
|
||||
@@ -975,13 +973,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
||||
} else { /* ZEND_OVERLOADED_FUNCTION */
|
||||
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (fci->object_pp) {
|
||||
zend_error_handling_t error_handling = EG(error_handling);
|
||||
zend_class_entry *exception_class = EG(exception_class);
|
||||
zend_error_handling error_handling;
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
Z_OBJ_HT_PP(fci->object_pp)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, *fci->object_pp, 1 TSRMLS_CC);
|
||||
EG(error_handling) = error_handling;
|
||||
EG(exception_class) = exception_class;
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
|
||||
}
|
||||
|
||||
@@ -2337,6 +2337,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
|
||||
|
||||
if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
zend_error_handling error_handling;
|
||||
ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
|
||||
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
|
||||
EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
|
||||
@@ -2351,12 +2352,14 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
}
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
@@ -2404,7 +2407,10 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (EX(object)) {
|
||||
zend_error_handling error_handling;
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
|
||||
}
|
||||
|
||||
@@ -302,6 +302,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
|
||||
|
||||
if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
zend_error_handling error_handling;
|
||||
ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
|
||||
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
|
||||
EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
|
||||
@@ -316,12 +317,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
arg_count--;
|
||||
}
|
||||
}
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
if (!zend_execute_internal) {
|
||||
/* saves one function call if zend_execute_internal is not used */
|
||||
((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
} else {
|
||||
zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
}
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
|
||||
if (!RETURN_VALUE_USED(opline)) {
|
||||
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
|
||||
@@ -369,7 +372,10 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
|
||||
/* Not sure what should be done here if it's a static method */
|
||||
if (EX(object)) {
|
||||
zend_error_handling error_handling;
|
||||
zend_save_error_handling(&error_handling TSRMLS_CC);
|
||||
Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
|
||||
zend_restore_error_handling(&error_handling TSRMLS_CC);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
|
||||
}
|
||||
|
||||
15
main/main.c
15
main/main.c
@@ -877,21 +877,6 @@ PHPAPI void php_html_puts(const char *str, uint size TSRMLS_DC)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_suppress_errors */
|
||||
PHPAPI void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC)
|
||||
{
|
||||
EG(error_handling) = error_handling;
|
||||
EG(exception_class) = exception_class;
|
||||
|
||||
if (error_handling == EH_NORMAL) {
|
||||
EG(user_error_handler) = EG(user_error_handler_old);
|
||||
} else {
|
||||
EG(user_error_handler_old) = EG(user_error_handler);
|
||||
EG(user_error_handler) = NULL;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ php_error_cb
|
||||
extended error handling function */
|
||||
static void php_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args)
|
||||
|
||||
@@ -286,7 +286,10 @@ END_EXTERN_C()
|
||||
#define error_handling_t zend_error_handling_t
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
PHPAPI void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC);
|
||||
static inline ZEND_ATTRIBUTE_DEPRECATED void php_set_error_handling(error_handling_t error_handling, zend_class_entry *exception_class TSRMLS_DC)
|
||||
{
|
||||
zend_replace_error_handling(error_handling, exception_class, NULL TSRMLS_CC);
|
||||
}
|
||||
static inline ZEND_ATTRIBUTE_DEPRECATED void php_std_error_handling() {}
|
||||
|
||||
PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args TSRMLS_DC);
|
||||
|
||||
Reference in New Issue
Block a user