summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend.c8
-rw-r--r--Zend/zend_exceptions.c216
-rw-r--r--Zend/zend_exceptions.h9
-rw-r--r--Zend/zend_interfaces.c20
-rw-r--r--Zend/zend_interfaces.h1
-rw-r--r--Zend/zend_language_scanner.c10
-rw-r--r--Zend/zend_language_scanner.l10
-rw-r--r--ext/soap/soap.c8
8 files changed, 156 insertions, 126 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index f262f8b5d7..1c2cfd6c77 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -882,7 +882,7 @@ void zenderror(const char *error) /* {{{ */
return;
}
- zend_throw_exception(zend_get_parse_exception(), error, E_PARSE);
+ zend_throw_exception(zend_get_parse_error(), error, E_PARSE);
}
/* }}} */
@@ -1059,7 +1059,7 @@ static void zend_error_va_list(int type, const char *format, va_list args)
va_start(args, format);
#endif
zend_vspprintf(&message, 0, format, args);
- zend_throw_exception(zend_get_engine_exception(), message, type);
+ zend_throw_exception(zend_get_error(), message, type);
efree(message);
#if !defined(HAVE_NORETURN) || defined(HAVE_NORETURN_ALIAS)
va_end(args);
@@ -1318,7 +1318,7 @@ ZEND_API void zend_type_error(const char *format, ...) /* {{{ */
va_start(va, format);
zend_vspprintf(&message, 0, format, va);
- zend_throw_exception(zend_get_type_exception(), message, E_ERROR);
+ zend_throw_exception(zend_get_type_error(), message, E_ERROR);
efree(message);
va_end(va);
} /* }}} */
@@ -1331,7 +1331,7 @@ ZEND_API void zend_internal_type_error(zend_bool throw_exception, const char *fo
va_start(va, format);
zend_vspprintf(&message, 0, format, va);
if (throw_exception) {
- zend_throw_exception(zend_get_type_exception(), message, E_ERROR);
+ zend_throw_exception(zend_get_type_error(), message, E_ERROR);
} else {
zend_error(E_WARNING, message);
}
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 671c09cd60..484fcdca60 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -30,33 +30,43 @@
#include "zend_dtrace.h"
#include "zend_smart_str.h"
-static zend_class_entry *base_exception_ce;
static zend_class_entry *default_exception_ce;
static zend_class_entry *error_exception_ce;
-static zend_class_entry *engine_exception_ce;
-static zend_class_entry *parse_exception_ce;
-static zend_class_entry *type_exception_ce;
+static zend_class_entry *error_ce;
+static zend_class_entry *parse_error_ce;
+static zend_class_entry *type_error_ce;
static zend_object_handlers default_exception_handlers;
ZEND_API void (*zend_throw_exception_hook)(zval *ex);
+ZEND_API zend_class_entry *zend_get_exception_base(zval *object)
+{
+ if (instanceof_function(Z_OBJCE_P(object), error_ce)) {
+ return error_ce;
+ }
+
+ return default_exception_ce;
+}
+
void zend_exception_set_previous(zend_object *exception, zend_object *add_previous)
{
zval tmp, *previous, zv, *pzv, rv;
+ zend_class_entry *base_ce;
if (exception == add_previous || !add_previous || !exception) {
return;
}
ZVAL_OBJ(&tmp, add_previous);
- if (!instanceof_function(Z_OBJCE(tmp), base_exception_ce)) {
+ if (!instanceof_function(Z_OBJCE(tmp), zend_ce_throwable)) {
zend_error_noreturn(E_CORE_ERROR, "Cannot set non exception as previous exception");
return;
}
ZVAL_OBJ(&zv, exception);
pzv = &zv;
do {
- previous = zend_read_property(base_exception_ce, pzv, "previous", sizeof("previous")-1, 1, &rv);
+ base_ce = zend_get_exception_base(pzv);
+ previous = zend_read_property(base_ce, pzv, "previous", sizeof("previous")-1, 1, &rv);
if (Z_TYPE_P(previous) == IS_NULL) {
- zend_update_property(base_exception_ce, pzv, "previous", sizeof("previous")-1, &tmp);
+ zend_update_property(base_ce, pzv, "previous", sizeof("previous")-1, &tmp);
GC_REFCOUNT(add_previous)--;
return;
}
@@ -110,7 +120,7 @@ ZEND_API void zend_throw_exception_internal(zval *exception) /* {{{ */
}
}
if (!EG(current_execute_data)) {
- if (exception && Z_OBJCE_P(exception) == parse_exception_ce) {
+ if (exception && Z_OBJCE_P(exception) == parse_error_ce) {
return;
}
if(EG(exception)) {
@@ -158,6 +168,7 @@ static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type,
zval obj;
zend_object *object;
zval trace;
+ zend_class_entry *base_ce;
Z_OBJ(obj) = object = zend_objects_new(class_type);
Z_OBJ_HT(obj) = &default_exception_handlers;
@@ -170,15 +181,17 @@ static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type,
array_init(&trace);
}
Z_SET_REFCOUNT(trace, 0);
+
+ base_ce = zend_get_exception_base(&obj);
- if (EXPECTED(class_type != parse_exception_ce)) {
- zend_update_property_string(base_exception_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename());
- zend_update_property_long(base_exception_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno());
+ if (EXPECTED(class_type != parse_error_ce)) {
+ zend_update_property_string(base_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename());
+ zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_executed_lineno());
} else {
- zend_update_property_string(base_exception_ce, &obj, "file", sizeof("file")-1, zend_get_compiled_filename()->val);
- zend_update_property_long(base_exception_ce, &obj, "line", sizeof("line")-1, zend_get_compiled_lineno());
+ zend_update_property_string(base_ce, &obj, "file", sizeof("file")-1, zend_get_compiled_filename()->val);
+ zend_update_property_long(base_ce, &obj, "line", sizeof("line")-1, zend_get_compiled_lineno());
}
- zend_update_property(base_exception_ce, &obj, "trace", sizeof("trace")-1, &trace);
+ zend_update_property(base_ce, &obj, "trace", sizeof("trace")-1, &trace);
return object;
}
@@ -196,6 +209,12 @@ static zend_object *zend_error_exception_new(zend_class_entry *class_type) /* {{
}
/* }}} */
+static zval *zend_get_exception_property(zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */
+{
+ return zend_read_property(zend_get_exception_base(object), object, name, name_length, silent, rv);
+}
+/* }}} */
+
/* {{{ proto Exception Exception::__clone()
Clone the exception object */
ZEND_METHOD(exception, __clone)
@@ -212,25 +231,27 @@ ZEND_METHOD(exception, __construct)
zend_string *message = NULL;
zend_long code = 0;
zval *object, *previous = NULL;
+ zend_class_entry *base_ce;
int argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|SlO!", &message, &code, &previous, base_exception_ce) == FAILURE) {
+ object = getThis();
+ base_ce = zend_get_exception_base(object);
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|SlO!", &message, &code, &previous, base_ce) == FAILURE) {
zend_error(E_EXCEPTION | E_ERROR, "Wrong parameters for Exception([string $exception [, long $code [, Exception $previous = NULL]]])");
return;
}
- object = getThis();
-
if (message) {
- zend_update_property_str(base_exception_ce, object, "message", sizeof("message")-1, message);
+ zend_update_property_str(base_ce, object, "message", sizeof("message")-1, message);
}
if (code) {
- zend_update_property_long(base_exception_ce, object, "code", sizeof("code")-1, code);
+ zend_update_property_long(base_ce, object, "code", sizeof("code")-1, code);
}
if (previous) {
- zend_update_property(base_exception_ce, object, "previous", sizeof("previous")-1, previous);
+ zend_update_property(base_ce, object, "previous", sizeof("previous")-1, previous);
}
}
/* }}} */
@@ -244,8 +265,8 @@ ZEND_METHOD(error_exception, __construct)
zval *object, *previous = NULL;
int argc = ZEND_NUM_ARGS();
size_t message_len, filename_len;
-
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|sllslO!", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, base_exception_ce) == FAILURE) {
+
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|sllslO!", &message, &message_len, &code, &severity, &filename, &filename_len, &lineno, &previous, default_exception_ce) == FAILURE) {
zend_error(E_EXCEPTION | E_ERROR, "Wrong parameters for ErrorException([string $exception [, long $code, [ long $severity, [ string $filename, [ long $lineno [, Exception $previous = NULL]]]]]])");
return;
}
@@ -253,25 +274,25 @@ ZEND_METHOD(error_exception, __construct)
object = getThis();
if (message) {
- zend_update_property_string(base_exception_ce, object, "message", sizeof("message")-1, message);
+ zend_update_property_string(default_exception_ce, object, "message", sizeof("message")-1, message);
}
if (code) {
- zend_update_property_long(base_exception_ce, object, "code", sizeof("code")-1, code);
+ zend_update_property_long(default_exception_ce, object, "code", sizeof("code")-1, code);
}
if (previous) {
- zend_update_property(base_exception_ce, object, "previous", sizeof("previous")-1, previous);
+ zend_update_property(default_exception_ce, object, "previous", sizeof("previous")-1, previous);
}
- zend_update_property_long(base_exception_ce, object, "severity", sizeof("severity")-1, severity);
+ zend_update_property_long(error_exception_ce, object, "severity", sizeof("severity")-1, severity);
if (argc >= 4) {
- zend_update_property_string(base_exception_ce, object, "file", sizeof("file")-1, filename);
+ zend_update_property_string(default_exception_ce, object, "file", sizeof("file")-1, filename);
if (argc < 5) {
lineno = 0; /* invalidate lineno */
}
- zend_update_property_long(base_exception_ce, object, "line", sizeof("line")-1, lineno);
+ zend_update_property_long(default_exception_ce, object, "line", sizeof("line")-1, lineno);
}
}
/* }}} */
@@ -282,9 +303,9 @@ ZEND_METHOD(error_exception, __construct)
}
#define GET_PROPERTY(object, name) \
- zend_read_property(base_exception_ce, (object), name, sizeof(name) - 1, 0, &rv)
+ zend_get_exception_property((object), name, sizeof(name) - 1, 0, &rv)
#define GET_PROPERTY_SILENT(object, name) \
- zend_read_property(base_exception_ce, (object), name, sizeof(name) - 1, 1, &rv)
+ zend_get_exception_property((object), name, sizeof(name) - 1, 1, &rv)
/* {{{ proto string Exception::getFile()
Get the file in which the exception occurred */
@@ -551,12 +572,17 @@ ZEND_METHOD(exception, getTraceAsString)
{
zval *trace, *frame, rv;
zend_ulong index;
+ zval *object;
+ zend_class_entry *base_ce;
smart_str str = {0};
uint32_t num = 0;
DEFAULT_0_PARAMS;
+
+ object = getThis();
+ base_ce = zend_get_exception_base(object);
- trace = zend_read_property(base_exception_ce, getThis(), "trace", sizeof("trace")-1, 1, &rv);
+ trace = zend_read_property(base_ce, getThis(), "trace", sizeof("trace")-1, 1, &rv);
if (Z_TYPE_P(trace) != IS_ARRAY) {
RETURN_FALSE;
}
@@ -618,6 +644,7 @@ zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /* {{{ */
ZEND_METHOD(exception, __toString)
{
zval trace, *exception;
+ zend_class_entry *base_ce;
zend_string *str;
zend_fcall_info fci;
zval fname, rv;
@@ -675,9 +702,12 @@ ZEND_METHOD(exception, __toString)
}
zval_dtor(&fname);
+ exception = getThis();
+ base_ce = zend_get_exception_base(exception);
+
/* We store the result in the private property string so we can access
* the result in uncaught exception handlers without memleaks. */
- zend_update_property_str(base_exception_ce, getThis(), "string", sizeof("string")-1, str);
+ zend_update_property_str(base_ce, exception, "string", sizeof("string")-1, str);
RETURN_STR(str);
}
@@ -734,66 +764,48 @@ void zend_register_default_exception(void) /* {{{ */
zend_class_entry ce;
zend_property_info *prop;
- INIT_CLASS_ENTRY(ce, "BaseException", default_exception_functions);
- base_exception_ce = zend_register_internal_class(&ce);
- base_exception_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
- base_exception_ce->create_object = NULL;
+ INIT_CLASS_ENTRY(ce, "Exception", default_exception_functions);
+ default_exception_ce = zend_register_internal_class_ex(&ce, NULL);
+ default_exception_ce->create_object = zend_default_exception_new;
memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
default_exception_handlers.clone_obj = NULL;
-
- zend_declare_property_string(base_exception_ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
- zend_declare_property_string(base_exception_ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
- zend_declare_property_long(base_exception_ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
- zend_declare_property_null(base_exception_ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
- zend_declare_property_null(base_exception_ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
- zend_declare_property_null(base_exception_ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE);
- zend_declare_property_null(base_exception_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
-
- INIT_CLASS_ENTRY(ce, "Exception", NULL);
- default_exception_ce = zend_register_internal_class_ex(&ce, base_exception_ce);
- default_exception_ce->create_object = zend_default_exception_new;
-
- /* A trick, to make visible private properties of BaseException */
- ZEND_HASH_FOREACH_PTR(&default_exception_ce->properties_info, prop) {
- if (prop->flags & ZEND_ACC_SHADOW) {
- if (prop->name->len == sizeof("\0BaseException\0string")-1) {
- prop->flags &= ~ZEND_ACC_SHADOW;
- prop->flags |= ZEND_ACC_PRIVATE;
- prop->ce = default_exception_ce;
- } else if (prop->name->len == sizeof("\0BaseException\0trace")-1) {
- prop->flags &= ~ZEND_ACC_SHADOW;
- prop->flags |= ZEND_ACC_PRIVATE;
- prop->ce = default_exception_ce;
- } else if (prop->name->len == sizeof("\0BaseException\0previous")-1) {
- prop->flags &= ~ZEND_ACC_SHADOW;
- prop->flags |= ZEND_ACC_PRIVATE;
- prop->ce = default_exception_ce;
- }
- }
- } ZEND_HASH_FOREACH_END();
+ zend_class_implements(default_exception_ce, 1, zend_ce_throwable);
+
+ zend_declare_property_string(default_exception_ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
+ zend_declare_property_string(default_exception_ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
+ zend_declare_property_long(default_exception_ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(default_exception_ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(default_exception_ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(default_exception_ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE);
+ zend_declare_property_null(default_exception_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
INIT_CLASS_ENTRY(ce, "ErrorException", error_exception_functions);
error_exception_ce = zend_register_internal_class_ex(&ce, default_exception_ce);
error_exception_ce->create_object = zend_error_exception_new;
zend_declare_property_long(error_exception_ce, "severity", sizeof("severity")-1, E_ERROR, ZEND_ACC_PROTECTED);
- INIT_CLASS_ENTRY(ce, "EngineException", NULL);
- engine_exception_ce = zend_register_internal_class_ex(&ce, base_exception_ce);
- engine_exception_ce->create_object = zend_default_exception_new;
-
- INIT_CLASS_ENTRY(ce, "ParseException", NULL);
- parse_exception_ce = zend_register_internal_class_ex(&ce, base_exception_ce);
- parse_exception_ce->create_object = zend_default_exception_new;
+ INIT_CLASS_ENTRY(ce, "Error", default_exception_functions);
+ error_ce = zend_register_internal_class_ex(&ce, NULL);
+ error_ce->create_object = zend_default_exception_new;
+ memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ default_exception_handlers.clone_obj = NULL;
+ zend_class_implements(error_ce, 1, zend_ce_throwable);
+
+ zend_declare_property_string(error_ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
+ zend_declare_property_string(error_ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
+ zend_declare_property_long(error_ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(error_ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(error_ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
+ zend_declare_property_null(error_ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE);
+ zend_declare_property_null(error_ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
- INIT_CLASS_ENTRY(ce, "TypeException", NULL);
- type_exception_ce = zend_register_internal_class_ex(&ce, engine_exception_ce);
- type_exception_ce->create_object = zend_default_exception_new;
-}
-/* }}} */
+ INIT_CLASS_ENTRY(ce, "ParseError", NULL);
+ parse_error_ce = zend_register_internal_class_ex(&ce, error_ce);
+ parse_error_ce->create_object = zend_default_exception_new;
-ZEND_API zend_class_entry *zend_exception_get_base(void) /* {{{ */
-{
- return base_exception_ce;
+ INIT_CLASS_ENTRY(ce, "TypeError", NULL);
+ type_error_ce = zend_register_internal_class_ex(&ce, error_ce);
+ type_error_ce->create_object = zend_default_exception_new;
}
/* }}} */
@@ -809,21 +821,21 @@ ZEND_API zend_class_entry *zend_get_error_exception(void) /* {{{ */
}
/* }}} */
-ZEND_API zend_class_entry *zend_get_engine_exception(void) /* {{{ */
+ZEND_API zend_class_entry *zend_get_error(void) /* {{{ */
{
- return engine_exception_ce;
+ return error_ce;
}
/* }}} */
-ZEND_API zend_class_entry *zend_get_parse_exception(void) /* {{{ */
+ZEND_API zend_class_entry *zend_get_parse_error(void) /* {{{ */
{
- return parse_exception_ce;
+ return parse_error_ce;
}
/* }}} */
-ZEND_API zend_class_entry *zend_get_type_exception(void) /* {{{ */
+ZEND_API zend_class_entry *zend_get_type_error(void) /* {{{ */
{
- return type_exception_ce;
+ return type_error_ce;
}
/* }}} */
@@ -833,8 +845,8 @@ ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const
zval ex;
if (exception_ce) {
- if (!instanceof_function(exception_ce, base_exception_ce)) {
- zend_error(E_NOTICE, "Exceptions must be derived from the Exception base class");
+ if (!instanceof_function(exception_ce, zend_ce_throwable)) {
+ zend_error(E_NOTICE, "Exceptions must implement Throwable");
exception_ce = default_exception_ce;
}
} else {
@@ -844,10 +856,10 @@ ZEND_API zend_object *zend_throw_exception(zend_class_entry *exception_ce, const
if (message) {
- zend_update_property_string(base_exception_ce, &ex, "message", sizeof("message")-1, message);
+ zend_update_property_string(exception_ce, &ex, "message", sizeof("message")-1, message);
}
if (code) {
- zend_update_property_long(base_exception_ce, &ex, "code", sizeof("code")-1, code);
+ zend_update_property_long(exception_ce, &ex, "code", sizeof("code")-1, code);
}
zend_throw_exception_internal(&ex);
@@ -875,7 +887,7 @@ ZEND_API zend_object *zend_throw_error_exception(zend_class_entry *exception_ce,
zval ex;
zend_object *obj = zend_throw_exception(exception_ce, message, code);
ZVAL_OBJ(&ex, obj);
- zend_update_property_long(base_exception_ce, &ex, "severity", sizeof("severity")-1, severity);
+ zend_update_property_long(error_exception_ce, &ex, "severity", sizeof("severity")-1, severity);
return obj;
}
/* }}} */
@@ -908,13 +920,13 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */
ZVAL_OBJ(&exception, ex);
ce_exception = Z_OBJCE(exception);
EG(exception) = NULL;
- if (ce_exception == parse_exception_ce || ce_exception == type_exception_ce) {
+ if (ce_exception == parse_error_ce || ce_exception == type_error_ce) {
zend_string *message = zval_get_string(GET_PROPERTY(&exception, "message"));
zend_string *file = zval_get_string(GET_PROPERTY_SILENT(&exception, "file"));
zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, "line"));
zend_long code = zval_get_long(GET_PROPERTY_SILENT(&exception, "code"));
- if (ce_exception == type_exception_ce && strstr(message->val, ", called in ")) {
+ if (ce_exception == type_error_ce && strstr(message->val, ", called in ")) {
zend_error_helper(code, file->val, line, "%s and defined", message->val);
} else {
zend_error_helper(code, file->val, line, "%s", message->val);
@@ -922,7 +934,7 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */
zend_string_release(file);
zend_string_release(message);
- } else if (instanceof_function(ce_exception, base_exception_ce)) {
+ } else if (instanceof_function(ce_exception, default_exception_ce) || instanceof_function(ce_exception, error_ce)) {
zval tmp, rv;
zend_string *str, *file = NULL;
zend_long line = 0;
@@ -932,7 +944,7 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */
if (Z_TYPE(tmp) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name->val);
} else {
- zend_update_property_string(base_exception_ce, &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp));
+ zend_update_property_string(zend_get_exception_base(&exception), &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp));
}
}
zval_ptr_dtor(&tmp);
@@ -942,10 +954,8 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */
ZVAL_OBJ(&zv, EG(exception));
/* do the best we can to inform about the inner exception */
- if (instanceof_function(ce_exception, base_exception_ce)) {
- file = zval_get_string(GET_PROPERTY_SILENT(&zv, "file"));
- line = zval_get_long(GET_PROPERTY_SILENT(&zv, "line"));
- }
+ file = zval_get_string(GET_PROPERTY_SILENT(&zv, "file"));
+ line = zval_get_long(GET_PROPERTY_SILENT(&zv, "line"));
zend_error_va(E_WARNING, (file && file->len > 0) ? file->val : NULL, line,
"Uncaught %s in exception handling during call to %s::__tostring()",
@@ -983,8 +993,8 @@ ZEND_API void zend_throw_exception_object(zval *exception) /* {{{ */
exception_ce = Z_OBJCE_P(exception);
- if (!exception_ce || !instanceof_function(exception_ce, base_exception_ce)) {
- zend_error(E_EXCEPTION | E_ERROR, "Exceptions must be valid objects derived from the Exception base class");
+ if (!exception_ce || !instanceof_function(exception_ce, zend_ce_throwable)) {
+ zend_error(E_EXCEPTION | E_ERROR, "Exceptions must be valid objects implementing Throwable");
return;
}
zend_throw_exception_internal(exception);
diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h
index e2c1f1fac7..bae4c35a78 100644
--- a/Zend/zend_exceptions.h
+++ b/Zend/zend_exceptions.h
@@ -34,12 +34,13 @@ ZEND_API void zend_throw_exception_internal(zval *exception);
void zend_register_default_exception(void);
-ZEND_API zend_class_entry *zend_exception_get_base(void);
+ZEND_API zend_class_entry *zend_get_exception_base(zval *object);
+
ZEND_API zend_class_entry *zend_exception_get_default(void);
ZEND_API zend_class_entry *zend_get_error_exception(void);
-ZEND_API zend_class_entry *zend_get_engine_exception(void);
-ZEND_API zend_class_entry *zend_get_parse_exception(void);
-ZEND_API zend_class_entry *zend_get_type_exception(void);
+ZEND_API zend_class_entry *zend_get_error(void);
+ZEND_API zend_class_entry *zend_get_parse_error(void);
+ZEND_API zend_class_entry *zend_get_type_error(void);
ZEND_API void zend_register_default_classes(void);
/* exception_ce NULL or zend_exception_get_default() or a derived class
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 54f8f8c117..2b8f8a25bc 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -28,6 +28,7 @@ ZEND_API zend_class_entry *zend_ce_aggregate;
ZEND_API zend_class_entry *zend_ce_iterator;
ZEND_API zend_class_entry *zend_ce_arrayaccess;
ZEND_API zend_class_entry *zend_ce_serializable;
+ZEND_API zend_class_entry *zend_ce_throwable;
/* {{{ zend_call_method
Only returns the returned zval if retval_ptr != NULL */
@@ -502,6 +503,19 @@ static int zend_implement_serializable(zend_class_entry *interface, zend_class_e
}
/* }}}*/
+/* {{{ zend_implement_traversable */
+static int zend_implement_throwable(zend_class_entry *interface, zend_class_entry *class_type)
+{
+ if (instanceof_function(class_type, zend_exception_get_default()) || instanceof_function(class_type, zend_get_error())) {
+ return SUCCESS;
+ }
+ zend_error_noreturn(E_CORE_ERROR, "Class %s cannot implement interface %s, extend Exception instead",
+ class_type->name->val,
+ interface->name->val);
+ return FAILURE;
+}
+/* }}} */
+
/* {{{ function tables */
const zend_function_entry zend_funcs_aggregate[] = {
ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
@@ -551,6 +565,8 @@ const zend_function_entry zend_funcs_serializable[] = {
};
/* }}} */
+const zend_function_entry *zend_funcs_throwable = NULL;
+
#define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
{\
zend_class_entry ce;\
@@ -575,7 +591,9 @@ ZEND_API void zend_register_interfaces(void)
REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
- REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
+ REGISTER_ITERATOR_INTERFACE(serializable, Serializable);
+
+ REGISTER_ITERATOR_INTERFACE(throwable, Throwable);
}
/* }}} */
diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h
index 8a8e0ce988..daf0aae5dc 100644
--- a/Zend/zend_interfaces.h
+++ b/Zend/zend_interfaces.h
@@ -31,6 +31,7 @@ extern ZEND_API zend_class_entry *zend_ce_aggregate;
extern ZEND_API zend_class_entry *zend_ce_iterator;
extern ZEND_API zend_class_entry *zend_ce_arrayaccess;
extern ZEND_API zend_class_entry *zend_ce_serializable;
+extern ZEND_API zend_class_entry *zend_ce_throwable;
typedef struct _zend_user_iterator {
zend_object_iterator it;
diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c
index abf93d587c..e3b2de1a79 100644
--- a/Zend/zend_language_scanner.c
+++ b/Zend/zend_language_scanner.c
@@ -998,7 +998,7 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
}
if (!valid) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid UTF-8 codepoint escape sequence", E_PARSE);
zval_ptr_dtor(zendlval);
return FAILURE;
@@ -1009,7 +1009,7 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
/* per RFC 3629, UTF-8 can only represent 21 bits */
if (codepoint > 0x10FFFF || errno) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid UTF-8 codepoint escape sequence: Codepoint too large", E_PARSE);
zval_ptr_dtor(zendlval);
return FAILURE;
@@ -2720,7 +2720,7 @@ yy136:
* Because the lexing itself doesn't do that for us
*/
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(), "Invalid numeric literal", E_PARSE);
+ zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
return T_ERROR;
}
} else {
@@ -2736,7 +2736,7 @@ yy136:
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid numeric literal", E_PARSE);
return T_ERROR;
}
@@ -2745,7 +2745,7 @@ yy136:
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(), "Invalid numeric literal", E_PARSE);
+ zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
return T_ERROR;
}
}
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index fdba4b9f07..1204287ad9 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -996,7 +996,7 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
}
if (!valid) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid UTF-8 codepoint escape sequence", E_PARSE);
zval_ptr_dtor(zendlval);
return FAILURE;
@@ -1007,7 +1007,7 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot
/* per RFC 3629, UTF-8 can only represent 21 bits */
if (codepoint > 0x10FFFF || errno) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid UTF-8 codepoint escape sequence: Codepoint too large", E_PARSE);
zval_ptr_dtor(zendlval);
return FAILURE;
@@ -1635,7 +1635,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
* Because the lexing itself doesn't do that for us
*/
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(), "Invalid numeric literal", E_PARSE);
+ zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
return T_ERROR;
}
} else {
@@ -1651,7 +1651,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(),
+ zend_throw_exception(zend_get_parse_error(),
"Invalid numeric literal", E_PARSE);
return T_ERROR;
}
@@ -1660,7 +1660,7 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
/* Also not an assert for the same reason */
if (end != yytext + yyleng) {
- zend_throw_exception(zend_get_parse_exception(), "Invalid numeric literal", E_PARSE);
+ zend_throw_exception(zend_get_parse_error(), "Invalid numeric literal", E_PARSE);
return T_ERROR;
}
}
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 120274b272..e6c7e5f4cd 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -1496,10 +1496,10 @@ static void _soap_server_exception(soapServicePtr service, sdlFunctionPtr functi
ZVAL_OBJ(&exception_object, EG(exception));
if (instanceof_function(Z_OBJCE(exception_object), soap_fault_class_entry)) {
soap_server_fault_ex(function, &exception_object, NULL);
- } else if (instanceof_function(Z_OBJCE(exception_object), zend_get_engine_exception())) {
+ } else if (instanceof_function(Z_OBJCE(exception_object), zend_get_error())) {
if (service->send_errors) {
zval rv;
- zend_string *msg = zval_get_string(zend_read_property(zend_exception_get_base(), &exception_object, "message", sizeof("message")-1, 0, &rv));
+ zend_string *msg = zval_get_string(zend_read_property(zend_get_exception_base(&exception_object), &exception_object, "message", sizeof("message")-1, 0, &rv));
add_soap_fault_ex(&exception_object, this_ptr, "Server", msg->val, NULL, NULL);
zend_string_release(msg);
} else {
@@ -2596,13 +2596,13 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
add_soap_fault(this_ptr, "Client", "SoapClient::__doRequest() failed", NULL, NULL);
ret = FALSE;
} else if (Z_TYPE_P(response) != IS_STRING) {
- if (EG(exception) && instanceof_function(EG(exception)->ce, zend_get_engine_exception())) {
+ if (EG(exception) && instanceof_function(EG(exception)->ce, zend_get_error())) {
zval rv;
zend_string *msg;
zval exception_object;
ZVAL_OBJ(&exception_object, EG(exception));
- msg = zval_get_string(zend_read_property(zend_exception_get_base(), &exception_object, "message", sizeof("message")-1, 0, &rv));
+ msg = zval_get_string(zend_read_property(zend_get_exception_base(&exception_object), &exception_object, "message", sizeof("message")-1, 0, &rv));
/* change class */
EG(exception)->ce = soap_fault_class_entry;
set_soap_fault(&exception_object, NULL, "Client", msg->val, NULL, NULL, NULL);