summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-10 14:14:36 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-11 12:41:15 +0200
commitdb233501ff9d56765ef4a870b777a643c2136711 (patch)
treedee39ce888124d9c70bff6e59ae62c580a983b37 /Zend
parentaab1445b4c30e81b0725470b2fc3e8112449eb5f (diff)
downloadphp-git-db233501ff9d56765ef4a870b777a643c2136711.tar.gz
Use clean shutdown on uncaught exception
Diffstat (limited to 'Zend')
-rw-r--r--Zend/tests/bug36268.phpt1
-rw-r--r--Zend/zend.c20
-rw-r--r--Zend/zend_errors.h3
-rw-r--r--Zend/zend_exceptions.c9
4 files changed, 21 insertions, 12 deletions
diff --git a/Zend/tests/bug36268.phpt b/Zend/tests/bug36268.phpt
index 8c93186c73..3bec61ff49 100644
--- a/Zend/tests/bug36268.phpt
+++ b/Zend/tests/bug36268.phpt
@@ -15,3 +15,4 @@ Fatal error: Uncaught Error: Call to undefined function bar() in %sbug36268.php:
Stack trace:
#0 {main}
thrown in %sbug36268.php on line 8
+Ha!
diff --git a/Zend/zend.c b/Zend/zend.c
index 4ad04f3876..ce98f50025 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -1246,7 +1246,7 @@ ZEND_API zval *zend_get_configuration_directive(zend_string *name) /* {{{ */
} while (0)
static ZEND_COLD void zend_error_va_list(
- int type, const char *error_filename, uint32_t error_lineno,
+ int orig_type, const char *error_filename, uint32_t error_lineno,
const char *format, va_list args)
{
va_list usr_copy;
@@ -1258,6 +1258,7 @@ static ZEND_COLD void zend_error_va_list(
zend_stack loop_var_stack;
zend_stack delayed_oplines_stack;
zend_class_entry *orig_fake_scope;
+ int type = orig_type & E_ALL;
/* Report about uncaught exception in case of fatal errors */
if (EG(exception)) {
@@ -1304,7 +1305,7 @@ static ZEND_COLD void zend_error_va_list(
if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF
|| !(EG(user_error_handler_error_reporting) & type)
|| EG(error_handling) != EH_NORMAL) {
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, format, args);
} else switch (type) {
case E_ERROR:
case E_PARSE:
@@ -1313,7 +1314,7 @@ 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(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, format, args);
break;
default:
/* Handle the error in user space */
@@ -1354,13 +1355,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(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, format, args);
}
zval_ptr_dtor(&retval);
}
} else if (!EG(exception)) {
/* The user error handler failed, use built-in error handler */
- zend_error_cb(type, error_filename, error_lineno, format, args);
+ zend_error_cb(orig_type, error_filename, error_lineno, format, args);
}
EG(fake_scope) = orig_fake_scope;
@@ -1626,9 +1627,10 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
int i;
zend_file_handle *file_handle;
zend_op_array *op_array;
+ int ret = SUCCESS;
va_start(files, file_count);
- for (i = 0; i < file_count; i++) {
+ for (i = 0; i < file_count && ret != FAILURE; i++) {
file_handle = va_arg(files, zend_file_handle *);
if (!file_handle) {
continue;
@@ -1648,18 +1650,18 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /
}
if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
+ ret = FAILURE;
}
}
destroy_op_array(op_array);
efree_size(op_array, sizeof(zend_op_array));
} else if (type==ZEND_REQUIRE) {
- va_end(files);
- return FAILURE;
+ ret = FAILURE;
}
}
va_end(files);
- return SUCCESS;
+ return ret;
}
/* }}} */
diff --git a/Zend/zend_errors.h b/Zend/zend_errors.h
index 6fda0f843e..dd7539523d 100644
--- a/Zend/zend_errors.h
+++ b/Zend/zend_errors.h
@@ -36,6 +36,9 @@
#define E_DEPRECATED (1<<13L)
#define E_USER_DEPRECATED (1<<14L)
+/* Indicates that this usually fatal error should not result in a bailout */
+#define E_DONT_BAIL (1<<15L)
+
#define E_ALL (E_ERROR | E_WARNING | E_PARSE | E_NOTICE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_RECOVERABLE_ERROR | E_DEPRECATED | E_USER_DEPRECATED | E_STRICT)
#define E_CORE (E_CORE_ERROR | E_CORE_WARNING)
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 9fd0176c34..6dfb374c2c 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -157,8 +157,9 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zval *exception) /* {{{ */
if (exception && (Z_OBJCE_P(exception) == zend_ce_parse_error || Z_OBJCE_P(exception) == zend_ce_compile_error)) {
return;
}
- if(EG(exception)) {
+ if (EG(exception)) {
zend_exception_error(EG(exception), E_ERROR);
+ zend_bailout();
}
zend_error_noreturn(E_CORE_ERROR, "Exception thrown without a stack frame");
}
@@ -991,7 +992,8 @@ 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(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR,
+ zend_error_helper(
+ (ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL,
ZSTR_VAL(file), line, "%s", ZSTR_VAL(message));
zend_string_release_ex(file, 0);
@@ -1034,7 +1036,8 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
file = zval_get_string(GET_PROPERTY_SILENT(&exception, ZEND_STR_FILE));
line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE));
- zend_error_va(severity, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
+ zend_error_va(severity | E_DONT_BAIL,
+ (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
"Uncaught %s\n thrown", ZSTR_VAL(str));
zend_string_release_ex(str, 0);