diff options
Diffstat (limited to 'Zend/zend_exceptions.c')
-rw-r--r-- | Zend/zend_exceptions.c | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index b4deb29a72..72a3c806e5 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -34,6 +34,7 @@ ZEND_API zend_class_entry *zend_ce_throwable; ZEND_API zend_class_entry *zend_ce_exception; ZEND_API zend_class_entry *zend_ce_error_exception; ZEND_API zend_class_entry *zend_ce_error; +ZEND_API zend_class_entry *zend_ce_compile_error; ZEND_API zend_class_entry *zend_ce_parse_error; ZEND_API zend_class_entry *zend_ce_type_error; ZEND_API zend_class_entry *zend_ce_argument_count_error; @@ -100,7 +101,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo previous = zend_read_property_ex(base_ce, ex, ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv); if (Z_TYPE_P(previous) == IS_NULL) { zend_update_property_ex(base_ce, ex, ZSTR_KNOWN(ZEND_STR_PREVIOUS), &pv); - GC_REFCOUNT(add_previous)--; + GC_DELREF(add_previous); return; } ex = previous; @@ -154,7 +155,7 @@ ZEND_API ZEND_COLD void zend_throw_exception_internal(zval *exception) /* {{{ */ } } if (!EG(current_execute_data)) { - if (exception && Z_OBJCE_P(exception) == zend_ce_parse_error) { + if (exception && (Z_OBJCE_P(exception) == zend_ce_parse_error || Z_OBJCE_P(exception) == zend_ce_compile_error)) { return; } if(EG(exception)) { @@ -221,7 +222,8 @@ static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, base_ce = i_get_exception_base(&obj); - if (EXPECTED(class_type != zend_ce_parse_error || !(filename = zend_get_compiled_filename()))) { + if (EXPECTED((class_type != zend_ce_parse_error && class_type != zend_ce_compile_error) + || !(filename = zend_get_compiled_filename()))) { ZVAL_STRING(&tmp, zend_get_executed_filename()); zend_update_property_ex(base_ce, &obj, ZSTR_KNOWN(ZEND_STR_FILE), &tmp); zval_ptr_dtor(&tmp); @@ -334,13 +336,12 @@ ZEND_METHOD(exception, __wakeup) ErrorException constructor */ ZEND_METHOD(error_exception, __construct) { - char *message = NULL, *filename = NULL; + zend_string *message = NULL, *filename = NULL; zend_long code = 0, severity = E_ERROR, lineno; zval tmp, *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, zend_ce_throwable) == FAILURE) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|SllSlO!", &message, &code, &severity, &filename, &lineno, &previous, zend_ce_throwable) == FAILURE) { zend_class_entry *ce; if (Z_TYPE(EX(This)) == IS_OBJECT) { @@ -357,7 +358,7 @@ ZEND_METHOD(error_exception, __construct) object = getThis(); if (message) { - ZVAL_STRING(&tmp, message); + ZVAL_STR_COPY(&tmp, message); zend_update_property_ex(zend_ce_exception, object, ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp); zval_ptr_dtor(&tmp); } @@ -375,7 +376,7 @@ ZEND_METHOD(error_exception, __construct) zend_update_property_ex(zend_ce_exception, object, ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp); if (argc >= 4) { - ZVAL_STRING(&tmp, filename); + ZVAL_STR_COPY(&tmp, filename); zend_update_property_ex(zend_ce_exception, object, ZSTR_KNOWN(ZEND_STR_FILE), &tmp); zval_ptr_dtor(&tmp); if (argc < 5) { @@ -532,7 +533,7 @@ static void _build_trace_args(zval *arg, smart_str *str) /* {{{ */ smart_str_appends(str, "Object("); smart_str_appends(str, ZSTR_VAL(class_name)); smart_str_appends(str, "), "); - zend_string_release(class_name); + zend_string_release_ex(class_name, 0); break; } } @@ -547,14 +548,14 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /* smart_str_append_long(str, num); smart_str_appendc(str, ' '); - file = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_FILE)); + file = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_FILE), 1); if (file) { if (Z_TYPE_P(file) != IS_STRING) { zend_error(E_WARNING, "Function name is no string"); smart_str_appends(str, "[unknown function]"); } else{ zend_long line; - tmp = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_LINE)); + tmp = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_LINE), 1); if (tmp) { if (Z_TYPE_P(tmp) == IS_LONG) { line = Z_LVAL_P(tmp); @@ -577,7 +578,7 @@ static void _build_trace_string(smart_str *str, HashTable *ht, uint32_t num) /* TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_TYPE)); TRACE_APPEND_KEY(ZSTR_KNOWN(ZEND_STR_FUNCTION)); smart_str_appendc(str, '('); - tmp = zend_hash_find(ht, ZSTR_KNOWN(ZEND_STR_ARGS)); + tmp = zend_hash_find_ex(ht, ZSTR_KNOWN(ZEND_STR_ARGS), 1); if (tmp) { if (Z_TYPE_P(tmp) == IS_ARRAY) { size_t last_len = ZSTR_LEN(str->s); @@ -688,7 +689,7 @@ ZEND_METHOD(exception, __toString) if ((Z_OBJCE_P(exception) == zend_ce_type_error || Z_OBJCE_P(exception) == zend_ce_argument_count_error) && strstr(ZSTR_VAL(message), ", called in ")) { zend_string *real_message = zend_strpprintf(0, "%s and defined", ZSTR_VAL(message)); - zend_string_release(message); + zend_string_release_ex(message, 0); message = real_message; } @@ -706,24 +707,24 @@ ZEND_METHOD(exception, __toString) ZSTR_LEN(prev_str) ? "\n\nNext " : "", ZSTR_VAL(prev_str)); } - zend_string_release(prev_str); - zend_string_release(message); - zend_string_release(file); + zend_string_release_ex(prev_str, 0); + zend_string_release_ex(message, 0); + zend_string_release_ex(file, 0); zval_ptr_dtor(&trace); - Z_OBJPROP_P(exception)->u.v.nApplyCount++; + Z_PROTECT_RECURSION_P(exception); exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS); - if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_OBJPROP_P(exception)->u.v.nApplyCount > 0) { + if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_IS_RECURSIVE_P(exception)) { break; } } - zend_string_release(fname); + zend_string_release_ex(fname, 0); exception = getThis(); /* Reset apply counts */ while (exception && Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(exception)) && instanceof_function(Z_OBJCE_P(exception), base_ce)) { - if (Z_OBJPROP_P(exception)->u.v.nApplyCount) { - Z_OBJPROP_P(exception)->u.v.nApplyCount--; + if (Z_IS_RECURSIVE_P(exception)) { + Z_UNPROTECT_RECURSION_P(exception); } else { break; } @@ -743,7 +744,7 @@ ZEND_METHOD(exception, __toString) /* }}} */ /** {{{ Throwable method definition */ -const zend_function_entry zend_funcs_throwable[] = { +static const zend_function_entry zend_funcs_throwable[] = { ZEND_ABSTRACT_ME(throwable, getMessage, NULL) ZEND_ABSTRACT_ME(throwable, getCode, NULL) ZEND_ABSTRACT_ME(throwable, getFile, NULL) @@ -809,7 +810,7 @@ void zend_register_default_exception(void) /* {{{ */ REGISTER_MAGIC_INTERFACE(throwable, Throwable); - memcpy(&default_exception_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + memcpy(&default_exception_handlers, &std_object_handlers, sizeof(zend_object_handlers)); default_exception_handlers.clone_obj = NULL; INIT_CLASS_ENTRY(ce, "Exception", default_exception_functions); @@ -843,8 +844,12 @@ void zend_register_default_exception(void) /* {{{ */ zend_declare_property_null(zend_ce_error, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE); zend_declare_property_null(zend_ce_error, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE); + INIT_CLASS_ENTRY(ce, "CompileError", NULL); + zend_ce_compile_error = zend_register_internal_class_ex(&ce, zend_ce_error); + zend_ce_compile_error->create_object = zend_default_exception_new; + INIT_CLASS_ENTRY(ce, "ParseError", NULL); - zend_ce_parse_error = zend_register_internal_class_ex(&ce, zend_ce_error); + zend_ce_parse_error = zend_register_internal_class_ex(&ce, zend_ce_compile_error); zend_ce_parse_error->create_object = zend_default_exception_new; INIT_CLASS_ENTRY(ce, "TypeError", NULL); @@ -964,15 +969,16 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* { ZVAL_OBJ(&exception, ex); ce_exception = Z_OBJCE(exception); EG(exception) = NULL; - if (ce_exception == zend_ce_parse_error) { + if (ce_exception == zend_ce_parse_error || ce_exception == zend_ce_compile_error) { zend_string *message = zval_get_string(GET_PROPERTY(&exception, ZEND_STR_MESSAGE)); 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(E_PARSE, ZSTR_VAL(file), line, "%s", ZSTR_VAL(message)); + zend_error_helper(ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR, + ZSTR_VAL(file), line, "%s", ZSTR_VAL(message)); - zend_string_release(file); - zend_string_release(message); + zend_string_release_ex(file, 0); + zend_string_release_ex(message, 0); } else if (instanceof_function(ce_exception, zend_ce_throwable)) { zval tmp, rv; zend_string *str, *file = NULL; @@ -1003,7 +1009,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* { ZSTR_VAL(Z_OBJCE(zv)->name), ZSTR_VAL(ce_exception->name)); if (file) { - zend_string_release(file); + zend_string_release_ex(file, 0); } } @@ -1014,8 +1020,8 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* { zend_error_va(severity, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line, "Uncaught %s\n thrown", ZSTR_VAL(str)); - zend_string_release(str); - zend_string_release(file); + zend_string_release_ex(str, 0); + zend_string_release_ex(file, 0); } else { zend_error(severity, "Uncaught exception '%s'", ZSTR_VAL(ce_exception->name)); } |