diff options
-rw-r--r-- | Zend/zend.c | 8 | ||||
-rw-r--r-- | Zend/zend_exceptions.c | 216 | ||||
-rw-r--r-- | Zend/zend_exceptions.h | 9 | ||||
-rw-r--r-- | Zend/zend_interfaces.c | 20 | ||||
-rw-r--r-- | Zend/zend_interfaces.h | 1 | ||||
-rw-r--r-- | Zend/zend_language_scanner.c | 10 | ||||
-rw-r--r-- | Zend/zend_language_scanner.l | 10 | ||||
-rw-r--r-- | ext/soap/soap.c | 8 |
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); |