diff options
Diffstat (limited to 'Zend/zend.c')
| -rw-r--r-- | Zend/zend.c | 342 |
1 files changed, 171 insertions, 171 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index b667514020..cbd5aef42b 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -32,6 +32,8 @@ #include "zend_smart_str.h" #include "zend_smart_string.h" #include "zend_cpuinfo.h" +#include "zend_attributes.h" +#include "zend_observer.h" static size_t global_map_ptr_last = 0; @@ -71,18 +73,19 @@ ZEND_API zend_class_entry *zend_standard_class_def = NULL; ZEND_API size_t (*zend_printf)(const char *format, ...); ZEND_API zend_write_func_t zend_write; ZEND_API FILE *(*zend_fopen)(const char *filename, zend_string **opened_path); -ZEND_API int (*zend_stream_open_function)(const char *filename, zend_file_handle *handle); +ZEND_API zend_result (*zend_stream_open_function)(const char *filename, zend_file_handle *handle); ZEND_API void (*zend_ticks_function)(int ticks); ZEND_API void (*zend_interrupt_function)(zend_execute_data *execute_data); -ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, const char *format, va_list args); +ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint32_t error_lineno, zend_string *message); void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap); void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap); -ZEND_API char *(*zend_getenv)(char *name, size_t name_len); +ZEND_API char *(*zend_getenv)(const char *name, size_t name_len); ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len); -ZEND_API int (*zend_post_startup_cb)(void) = NULL; +ZEND_API zend_result (*zend_post_startup_cb)(void) = NULL; ZEND_API void (*zend_post_shutdown_cb)(void) = NULL; -ZEND_API int (*zend_preload_autoload)(zend_string *filename) = NULL; +ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename) = NULL; +/* This callback must be signal handler safe! */ void (*zend_on_timeout)(int seconds); static void (*zend_message_dispatcher_p)(zend_long message, const void *data); @@ -95,7 +98,7 @@ ZEND_API zend_bool zend_rc_debug = 0; static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */ { if (!new_value) { - EG(error_reporting) = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED; + EG(error_reporting) = E_ALL; } else { EG(error_reporting) = atoi(ZSTR_VAL(new_value)); } @@ -139,18 +142,9 @@ static ZEND_INI_MH(OnUpdateScriptEncoding) /* {{{ */ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */ { - zend_long *p, val; -#ifndef ZTS - char *base = (char *) mh_arg2; -#else - char *base; - - base = (char *) ts_resource(*((int *) mh_arg2)); -#endif - - p = (zend_long *) (base+(size_t) mh_arg1); + zend_long *p = (zend_long *) ZEND_INI_GET_ADDR(); - val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); + zend_long val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); if (stage != ZEND_INI_STAGE_STARTUP && stage != ZEND_INI_STAGE_SHUTDOWN && @@ -165,6 +159,20 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */ } /* }}} */ +static ZEND_INI_MH(OnSetExceptionStringParamMaxLen) /* {{{ */ +{ + zend_long i; + + ZEND_ATOL(i, ZSTR_VAL(new_value)); + if (i >= 0 && i <= 1000000) { + EG(exception_string_param_max_len) = i; + return SUCCESS; + } else { + return FAILURE; + } +} +/* }}} */ + #if ZEND_DEBUG # define SIGNAL_CHECK_DEFAULT "1" #else @@ -182,6 +190,7 @@ ZEND_INI_BEGIN() STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals) #endif STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals) + STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals) ZEND_INI_END() ZEND_API size_t zend_vspprintf(char **pbuf, size_t max_len, const char *format, va_list ap) /* {{{ */ @@ -355,7 +364,7 @@ static void print_flat_hash(HashTable *ht) /* {{{ */ } /* }}} */ -ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */ +ZEND_API bool zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */ { if (Z_TYPE_P(expr) == IS_STRING) { return 0; @@ -395,9 +404,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */ } print_flat_hash(Z_ARRVAL_P(expr)); ZEND_PUTS(")"); - if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr)); - } + GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr)); break; case IS_OBJECT: { @@ -443,9 +450,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /* GC_PROTECT_RECURSION(Z_ARRVAL_P(expr)); } print_hash(buf, Z_ARRVAL_P(expr), indent, 0); - if (!(GC_FLAGS(Z_ARRVAL_P(expr)) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(Z_ARRVAL_P(expr)); - } + GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(expr)); break; case IS_OBJECT: { @@ -542,7 +547,7 @@ static void zend_get_windows_version_info(OSVERSIONINFOEX *osvi) /* {{{ */ ZeroMemory(osvi, sizeof(OSVERSIONINFOEX)); osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!GetVersionEx((OSVERSIONINFO *) osvi)) { - ZEND_ASSERT(0); /* Should not happen as sizeof is used. */ + ZEND_UNREACHABLE(); /* Should not happen as sizeof is used. */ } } /* }}} */ @@ -601,12 +606,20 @@ static void function_copy_ctor(zval *zv) /* {{{ */ new_arg_info = pemalloc(sizeof(zend_arg_info) * num_args, 1); memcpy(new_arg_info, arg_info, sizeof(zend_arg_info) * num_args); for (i = 0 ; i < num_args; i++) { - if (ZEND_TYPE_IS_CLASS(arg_info[i].type)) { + if (ZEND_TYPE_HAS_LIST(arg_info[i].type)) { + zend_type_list *old_list = ZEND_TYPE_LIST(arg_info[i].type); + zend_type_list *new_list = pemalloc(ZEND_TYPE_LIST_SIZE(old_list->num_types), 1); + memcpy(new_list, old_list, ZEND_TYPE_LIST_SIZE(old_list->num_types)); + ZEND_TYPE_SET_PTR(new_arg_info[i].type, new_list); + + zend_type *list_type; + ZEND_TYPE_LIST_FOREACH(new_list, list_type) { + zend_string *name = zend_string_dup(ZEND_TYPE_NAME(*list_type), 1); + ZEND_TYPE_SET_PTR(*list_type, name); + } ZEND_TYPE_LIST_FOREACH_END(); + } else if (ZEND_TYPE_HAS_NAME(arg_info[i].type)) { zend_string *name = zend_string_dup(ZEND_TYPE_NAME(arg_info[i].type), 1); - - new_arg_info[i].type = - ZEND_TYPE_ENCODE_CLASS( - name, ZEND_TYPE_ALLOW_NULL(arg_info[i].type)); + ZEND_TYPE_SET_PTR(new_arg_info[i].type, name); } } func->common.arg_info = new_arg_info + 1; @@ -632,31 +645,33 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{ compiler_globals->compiled_filename = NULL; compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init_ex(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0); + zend_hash_init(compiler_globals->function_table, 1024, NULL, ZEND_FUNCTION_DTOR, 1); zend_hash_copy(compiler_globals->function_table, global_function_table, function_copy_ctor); compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init_ex(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1, 0); + zend_hash_init(compiler_globals->class_table, 64, NULL, ZEND_CLASS_DTOR, 1); zend_hash_copy(compiler_globals->class_table, global_class_table, zend_class_add_ref); zend_set_default_compile_time_values(); compiler_globals->auto_globals = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0); + zend_hash_init(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1); zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor); compiler_globals->script_encoding_list = NULL; #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET /* Map region is going to be created and resized at run-time. */ - compiler_globals->map_ptr_base = NULL; + ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL); compiler_globals->map_ptr_size = 0; compiler_globals->map_ptr_last = global_map_ptr_last; if (compiler_globals->map_ptr_last) { /* Allocate map_ptr table */ + void *base; compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096); - compiler_globals->map_ptr_base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1); - memset(compiler_globals->map_ptr_base, 0, compiler_globals->map_ptr_last * sizeof(void*)); + base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1); + ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, base); + memset(base, 0, compiler_globals->map_ptr_last * sizeof(void*)); } #else # error "Unknown ZEND_MAP_PTR_KIND" @@ -681,9 +696,9 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{ if (compiler_globals->script_encoding_list) { pefree((char*)compiler_globals->script_encoding_list, 1); } - if (compiler_globals->map_ptr_base) { - free(compiler_globals->map_ptr_base); - compiler_globals->map_ptr_base = NULL; + if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) { + free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)); + ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL); compiler_globals->map_ptr_size = 0; } } @@ -737,9 +752,8 @@ static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{ static void zend_new_thread_end_handler(THREAD_T thread_id) /* {{{ */ { - if (zend_copy_ini_directives() == SUCCESS) { - zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP); - } + zend_copy_ini_directives(); + zend_ini_refresh_caches(ZEND_INI_STAGE_STARTUP); } /* }}} */ #endif @@ -783,7 +797,7 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */ } /* }}} */ -int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ +void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ { #ifdef ZTS zend_compiler_globals *compiler_globals; @@ -816,7 +830,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ /* Set up utility functions and values */ zend_error_cb = utility_functions->error_function; zend_printf = utility_functions->printf_function; - zend_write = (zend_write_func_t) utility_functions->write_function; + zend_write = utility_functions->write_function; zend_fopen = utility_functions->fopen_function; if (!zend_fopen) { zend_fopen = zend_fopen_wrapper; @@ -833,7 +847,7 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_interrupt_function = NULL; -#if HAVE_DTRACE +#ifdef HAVE_DTRACE /* build with dtrace support */ { char *tmp = getenv("USE_ZEND_DTRACE"); @@ -843,6 +857,8 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_compile_file = dtrace_compile_file; zend_execute_ex = dtrace_execute_ex; zend_execute_internal = dtrace_execute_internal; + + zend_observer_error_register(dtrace_error_notify_cb); } else { zend_compile_file = compile_file; zend_execute_ex = execute_ex; @@ -871,12 +887,12 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable)); GLOBAL_CONSTANTS_TABLE = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1, 0); - zend_hash_init_ex(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1, 0); - zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1, 0); - zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1, 0); + zend_hash_init(GLOBAL_FUNCTION_TABLE, 1024, NULL, ZEND_FUNCTION_DTOR, 1); + zend_hash_init(GLOBAL_CLASS_TABLE, 64, NULL, ZEND_CLASS_DTOR, 1); + zend_hash_init(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, auto_global_dtor, 1); + zend_hash_init(GLOBAL_CONSTANTS_TABLE, 128, NULL, ZEND_CONSTANT_DTOR, 1); - zend_hash_init_ex(&module_registry, 32, NULL, module_destructor_zval, 1, 0); + zend_hash_init(&module_registry, 32, NULL, module_destructor_zval, 1); zend_init_rsrc_list_dtors(); #ifdef ZTS @@ -912,10 +928,10 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ */ CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ??? CG(map_ptr_last) = 0; - CG(map_ptr_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1); + ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), pemalloc(CG(map_ptr_size) * sizeof(void*), 1)); # elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET /* Map region is going to be created and resized at run-time. */ - CG(map_ptr_base) = NULL; + ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL); CG(map_ptr_size) = 0; CG(map_ptr_last) = 0; # else @@ -946,8 +962,6 @@ int zend_startup(zend_utility_functions *utility_functions) /* {{{ */ tsrm_set_new_thread_end_handler(zend_new_thread_end_handler); tsrm_set_shutdown_handler(zend_interned_strings_dtor); #endif - - return SUCCESS; } /* }}} */ @@ -959,6 +973,15 @@ void zend_register_standard_ini_entries(void) /* {{{ */ } /* }}} */ +static zend_class_entry *resolve_type_name(zend_string *type_name) { + zend_string *lc_type_name = zend_string_tolower(type_name); + zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lc_type_name); + + ZEND_ASSERT(ce && ce->type == ZEND_INTERNAL_CLASS); + zend_string_release(lc_type_name); + return ce; +} + static void zend_resolve_property_types(void) /* {{{ */ { zend_class_entry *ce; @@ -971,16 +994,14 @@ static void zend_resolve_property_types(void) /* {{{ */ if (UNEXPECTED(ZEND_CLASS_HAS_TYPE_HINTS(ce))) { ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { - if (ZEND_TYPE_IS_NAME(prop_info->type)) { - zend_string *type_name = ZEND_TYPE_NAME(prop_info->type); - zend_string *lc_type_name = zend_string_tolower(type_name); - zend_class_entry *prop_ce = zend_hash_find_ptr(CG(class_table), lc_type_name); - - ZEND_ASSERT(prop_ce && prop_ce->type == ZEND_INTERNAL_CLASS); - prop_info->type = ZEND_TYPE_ENCODE_CE(prop_ce, ZEND_TYPE_ALLOW_NULL(prop_info->type)); - zend_string_release(lc_type_name); - zend_string_release(type_name); - } + zend_type *single_type; + ZEND_TYPE_FOREACH(prop_info->type, single_type) { + if (ZEND_TYPE_HAS_NAME(*single_type)) { + zend_string *type_name = ZEND_TYPE_NAME(*single_type); + ZEND_TYPE_SET_CE(*single_type, resolve_type_name(type_name)); + zend_string_release(type_name); + } + } ZEND_TYPE_FOREACH_END(); } ZEND_HASH_FOREACH_END(); } ce->ce_flags |= ZEND_ACC_PROPERTY_TYPES_RESOLVED; @@ -991,7 +1012,7 @@ static void zend_resolve_property_types(void) /* {{{ */ /* Unlink the global (r/o) copies of the class, function and constant tables, * and use a fresh r/w copy for the startup thread */ -int zend_post_startup(void) /* {{{ */ +zend_result zend_post_startup(void) /* {{{ */ { #ifdef ZTS zend_encoding **script_encoding_list; @@ -1003,7 +1024,7 @@ int zend_post_startup(void) /* {{{ */ zend_resolve_property_types(); if (zend_post_startup_cb) { - int (*cb)(void) = zend_post_startup_cb; + zend_result (*cb)(void) = zend_post_startup_cb; zend_post_startup_cb = NULL; if (cb() != SUCCESS) { @@ -1025,8 +1046,10 @@ int zend_post_startup(void) /* {{{ */ compiler_globals->function_table = NULL; free(compiler_globals->class_table); compiler_globals->class_table = NULL; - free(compiler_globals->map_ptr_base); - compiler_globals->map_ptr_base = NULL; + if (ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)) { + free(ZEND_MAP_PTR_REAL_BASE(compiler_globals->map_ptr_base)); + } + ZEND_MAP_PTR_SET_REAL_BASE(compiler_globals->map_ptr_base, NULL); if ((script_encoding_list = (zend_encoding **)compiler_globals->script_encoding_list)) { compiler_globals_ctor(compiler_globals); compiler_globals->script_encoding_list = (const zend_encoding **)script_encoding_list; @@ -1072,6 +1095,7 @@ void zend_shutdown(void) /* {{{ */ zend_hash_destroy(GLOBAL_CONSTANTS_TABLE); free(GLOBAL_CONSTANTS_TABLE); zend_shutdown_strtod(); + zend_attributes_shutdown(); #ifdef ZTS GLOBAL_FUNCTION_TABLE = NULL; @@ -1081,13 +1105,13 @@ void zend_shutdown(void) /* {{{ */ ts_free_id(executor_globals_id); ts_free_id(compiler_globals_id); #else - if (CG(map_ptr_base)) { - free(CG(map_ptr_base)); - CG(map_ptr_base) = NULL; + if (ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base))) { + free(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base))); + ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), NULL); CG(map_ptr_size) = 0; } if (CG(script_encoding_list)) { - free(CG(script_encoding_list)); + free(ZEND_VOIDP(CG(script_encoding_list))); CG(script_encoding_list) = NULL; CG(script_encoding_list_size) = 0; } @@ -1156,7 +1180,7 @@ ZEND_API void zend_append_version_info(const zend_extension *extension) /* {{{ * } /* }}} */ -ZEND_API char *get_zend_version(void) /* {{{ */ +ZEND_API const char *get_zend_version(void) /* {{{ */ { return zend_version_info; } @@ -1172,8 +1196,9 @@ ZEND_API void zend_activate(void) /* {{{ */ init_executor(); startup_scanner(); if (CG(map_ptr_last)) { - memset(CG(map_ptr_base), 0, CG(map_ptr_last) * sizeof(void*)); + memset(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), 0, CG(map_ptr_last) * sizeof(void*)); } + zend_observer_activate(); } /* }}} */ @@ -1190,6 +1215,8 @@ ZEND_API void zend_deactivate(void) /* {{{ */ /* we're no longer executing anything */ EG(current_execute_data) = NULL; + zend_observer_deactivate(); + zend_try { shutdown_scanner(); } zend_end_try(); @@ -1259,69 +1286,48 @@ 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, - const char *format, va_list args) +static ZEND_COLD void zend_error_impl( + int orig_type, const char *error_filename, uint32_t error_lineno, zend_string *message) { - va_list usr_copy; - zval params[5]; + zval params[4]; zval retval; zval orig_user_error_handler; zend_bool in_compilation; zend_class_entry *saved_class_entry; zend_stack loop_var_stack; zend_stack delayed_oplines_stack; - zend_array *symbol_table; - zend_class_entry *orig_fake_scope; + int type = orig_type & E_ALL; /* Report about uncaught exception in case of fatal errors */ if (EG(exception)) { zend_execute_data *ex; const zend_op *opline; - switch (type) { - case E_CORE_ERROR: - case E_ERROR: - case E_RECOVERABLE_ERROR: - case E_PARSE: - case E_COMPILE_ERROR: - case E_USER_ERROR: - ex = EG(current_execute_data); - opline = NULL; - while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { - ex = ex->prev_execute_data; - } - if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION && - EG(opline_before_exception)) { - opline = EG(opline_before_exception); - } - zend_exception_error(EG(exception), E_WARNING); - EG(exception) = NULL; - if (opline) { - ex->opline = opline; - } - break; - default: - break; + if (type & E_FATAL_ERRORS) { + ex = EG(current_execute_data); + opline = NULL; + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { + ex = ex->prev_execute_data; + } + if (ex && ex->opline->opcode == ZEND_HANDLE_EXCEPTION && + EG(opline_before_exception)) { + opline = EG(opline_before_exception); + } + zend_exception_error(EG(exception), E_WARNING); + EG(exception) = NULL; + if (opline) { + ex->opline = opline; + } } } -#ifdef HAVE_DTRACE - if (DTRACE_ERROR_ENABLED()) { - char *dtrace_error_buffer; - va_copy(usr_copy, args); - zend_vspprintf(&dtrace_error_buffer, 0, format, usr_copy); - va_end(usr_copy); - DTRACE_ERROR(dtrace_error_buffer, (char *)error_filename, error_lineno); - efree(dtrace_error_buffer); - } -#endif /* HAVE_DTRACE */ + zend_observer_error_notify(type, error_filename, error_lineno, message); /* if we don't have a user defined error handler */ 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, message); } else switch (type) { case E_ERROR: case E_PARSE: @@ -1330,14 +1336,11 @@ 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, message); break; default: /* Handle the error in user space */ - va_copy(usr_copy, args); - ZVAL_STR(¶ms[1], zend_vstrpprintf(0, format, usr_copy)); - va_end(usr_copy); - + ZVAL_STR_COPY(¶ms[1], message); ZVAL_LONG(¶ms[0], type); if (error_filename) { @@ -1348,15 +1351,6 @@ static ZEND_COLD void zend_error_va_list( ZVAL_LONG(¶ms[3], error_lineno); - symbol_table = zend_rebuild_symbol_table(); - - /* during shutdown the symbol table table can be still null */ - if (!symbol_table) { - ZVAL_NULL(¶ms[4]); - } else { - ZVAL_ARR(¶ms[4], zend_array_dup(symbol_table)); - } - ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler)); ZVAL_UNDEF(&EG(user_error_handler)); @@ -1374,23 +1368,18 @@ static ZEND_COLD void zend_error_va_list( CG(in_compilation) = 0; } - orig_fake_scope = EG(fake_scope); - EG(fake_scope) = NULL; - - if (call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 5, params) == SUCCESS) { + 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, message); } 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, message); } - EG(fake_scope) = orig_fake_scope; - if (in_compilation) { CG(active_class_entry) = saved_class_entry; RESTORE_STACK(loop_var_stack); @@ -1398,7 +1387,6 @@ static ZEND_COLD void zend_error_va_list( CG(in_compilation) = 1; } - zval_ptr_dtor(¶ms[4]); zval_ptr_dtor(¶ms[2]); zval_ptr_dtor(¶ms[1]); @@ -1423,6 +1411,15 @@ static ZEND_COLD void zend_error_va_list( } /* }}} */ +static ZEND_COLD void zend_error_va_list( + int orig_type, const char *error_filename, uint32_t error_lineno, + const char *format, va_list args) +{ + zend_string *message = zend_vstrpprintf(0, format, args); + zend_error_impl(orig_type, error_filename, error_lineno, message); + zend_string_release(message); +} + static ZEND_COLD void get_filename_lineno(int type, const char **filename, uint32_t *lineno) { /* Obtain relevant filename and lineno */ switch (type) { @@ -1511,7 +1508,6 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_at_noreturn( /* Should never reach this. */ abort(); } -/* }}} */ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) { @@ -1526,19 +1522,20 @@ ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char * /* Should never reach this. */ abort(); } -/* }}} */ + +ZEND_API ZEND_COLD void zend_error_zstr(int type, zend_string *message) { + const char *filename; + uint32_t lineno; + get_filename_lineno(type, &filename, &lineno); + zend_error_impl(type, filename, lineno, message); +} ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ { va_list va; char *message = NULL; - if (exception_ce) { - if (!instanceof_function(exception_ce, zend_ce_error)) { - zend_error(E_NOTICE, "Error exceptions must be derived from Error"); - exception_ce = zend_ce_error; - } - } else { + if (!exception_ce) { exception_ce = zend_ce_error; } @@ -1574,37 +1571,28 @@ ZEND_API ZEND_COLD void zend_type_error(const char *format, ...) /* {{{ */ va_end(va); } /* }}} */ -ZEND_API ZEND_COLD void zend_internal_type_error(zend_bool throw_exception, const char *format, ...) /* {{{ */ +ZEND_API ZEND_COLD void zend_argument_count_error(const char *format, ...) /* {{{ */ { va_list va; char *message = NULL; va_start(va, format); zend_vspprintf(&message, 0, format, va); - if (throw_exception) { - zend_throw_exception(zend_ce_type_error, message, 0); - } else { - zend_error(E_WARNING, "%s", message); - } + zend_throw_exception(zend_ce_argument_count_error, message, 0); efree(message); va_end(va); } /* }}} */ -ZEND_API ZEND_COLD void zend_internal_argument_count_error(zend_bool throw_exception, const char *format, ...) /* {{{ */ +ZEND_API ZEND_COLD void zend_value_error(const char *format, ...) /* {{{ */ { va_list va; char *message = NULL; va_start(va, format); zend_vspprintf(&message, 0, format, va); - if (throw_exception) { - zend_throw_exception(zend_ce_argument_count_error, message, 0); - } else { - zend_error(E_WARNING, "%s", message); - } + zend_throw_exception(zend_ce_value_error, message, 0); efree(message); - va_end(va); } /* }}} */ @@ -1639,6 +1627,11 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */ zval orig_user_exception_handler; zval params[1], retval2; zend_object *old_exception; + + if (zend_is_unwind_exit(EG(exception))) { + return; + } + old_exception = EG(exception); EG(exception) = NULL; ZVAL_OBJ(¶ms[0], old_exception); @@ -1656,12 +1649,13 @@ ZEND_API ZEND_COLD void zend_user_exception_handler(void) /* {{{ */ } } /* }}} */ -ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */ +ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count, ...) /* {{{ */ { va_list files; int i; zend_file_handle *file_handle; zend_op_array *op_array; + zend_result ret = SUCCESS; va_start(files, file_count); for (i = 0; i < file_count; i++) { @@ -1670,6 +1664,13 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) / continue; } + if (ret == FAILURE) { + /* If a failure occurred in one of the earlier files, + * only destroy the following file handles. */ + zend_file_handle_dtor(file_handle); + continue; + } + op_array = zend_compile_file(file_handle, type); if (file_handle->opened_path) { zend_hash_add_empty_element(&EG(included_files), file_handle->opened_path); @@ -1683,19 +1684,18 @@ ZEND_API int zend_execute_scripts(int type, zval *retval, int file_count, ...) / zend_user_exception_handler(); } if (EG(exception)) { - zend_exception_error(EG(exception), E_ERROR); + ret = zend_exception_error(EG(exception), E_ERROR); } } 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; } /* }}} */ @@ -1741,16 +1741,16 @@ ZEND_API void *zend_map_ptr_new(void) if (CG(map_ptr_last) >= CG(map_ptr_size)) { #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR // TODO: error ??? - ZEND_ASSERT(0); + ZEND_UNREACHABLE(); #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET /* Grow map_ptr table */ CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096); - CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1); + ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1)); #else # error "Unknown ZEND_MAP_PTR_KIND" #endif } - ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last); + ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last); *ptr = NULL; CG(map_ptr_last)++; #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR @@ -1770,16 +1770,16 @@ ZEND_API void zend_map_ptr_extend(size_t last) if (last >= CG(map_ptr_size)) { #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR /* This may never happen */ - ZEND_ASSERT(0); + ZEND_UNREACHABLE(); #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET /* Grow map_ptr table */ CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096); - CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1); + ZEND_MAP_PTR_SET_REAL_BASE(CG(map_ptr_base), perealloc(ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)), CG(map_ptr_size) * sizeof(void*), 1)); #else # error "Unknown ZEND_MAP_PTR_KIND" #endif } - ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last); + ptr = (void**)ZEND_MAP_PTR_REAL_BASE(CG(map_ptr_base)) + CG(map_ptr_last); memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*)); CG(map_ptr_last) = last; } |
