summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.h9
-rw-r--r--Zend/zend_API.c31
-rw-r--r--Zend/zend_execute_API.c15
-rw-r--r--Zend/zend_vm_def.h6
-rw-r--r--Zend/zend_vm_execute.h6
-rw-r--r--main/main.c15
-rw-r--r--main/php.h5
7 files changed, 62 insertions, 25 deletions
diff --git a/Zend/zend.h b/Zend/zend.h
index 0d09f4bc0d..7f8201c743 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -749,6 +749,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);
+
#endif /* ZEND_H */
/*
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index da7548f407..e15109bcff 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -3463,6 +3463,37 @@ ZEND_API zval *zend_read_static_property(zend_class_entry *scope, char *name, in
}
/* }}} */
+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
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 343c0f18c2..00da9eac55 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -890,16 +890,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)
@@ -920,11 +918,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
/* 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");
}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 63c375a55c..d750469012 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2273,6 +2273,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;
@@ -2287,12 +2288,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(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, 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);
@@ -2340,7 +2343,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");
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index a8afd94dba..a8bfe54d1b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -294,6 +294,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;
@@ -308,12 +309,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(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, 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);
@@ -361,7 +364,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");
}
diff --git a/main/main.c b/main/main.c
index d1e56b76da..3662e90687 100644
--- a/main/main.c
+++ b/main/main.c
@@ -777,21 +777,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)
diff --git a/main/php.h b/main/php.h
index ca20596797..88a94da5c9 100644
--- a/main/php.h
+++ b/main/php.h
@@ -287,7 +287,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) PHP_ATTRIBUTE_FORMAT(printf, 4, 0);