--- embedaddon/php/Zend/zend_API.c 2012/05/29 12:34:35 1.1.1.2 +++ embedaddon/php/Zend/zend_API.c 2013/07/22 01:32:15 1.1.1.3 @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.1.1.2 2012/05/29 12:34:35 misho Exp $ */ +/* $Id: zend_API.c,v 1.1.1.3 2013/07/22 01:32:15 misho Exp $ */ #include "zend.h" #include "zend_execute.h" @@ -1022,6 +1022,41 @@ ZEND_API void zend_merge_properties(zval *obj, HashTab } /* }}} */ +static int zval_update_class_constant(zval **pp, int is_static, int offset TSRMLS_DC) /* {{{ */ +{ + if ((Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || + (Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_ARRAY) { + zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry); + + if ((*scope)->parent) { + zend_class_entry *ce = *scope; + HashPosition pos; + zend_property_info *prop_info; + + do { + for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS; + zend_hash_move_forward_ex(&ce->properties_info, &pos)) { + if (is_static == ((prop_info->flags & ZEND_ACC_STATIC) != 0) && + offset == prop_info->offset) { + int ret; + zend_class_entry *old_scope = *scope; + *scope = prop_info->ce; + ret = zval_update_constant(pp, (void*)1 TSRMLS_CC); + *scope = old_scope; + return ret; + } + } + ce = ce->parent; + } while (ce); + + } + return zval_update_constant(pp, (void*)1 TSRMLS_CC); + } + return 0; +} +/* }}} */ + ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0 || (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count)) { @@ -1034,7 +1069,7 @@ ZEND_API void zend_update_class_constants(zend_class_e for (i = 0; i < class_type->default_properties_count; i++) { if (class_type->default_properties_table[i]) { - zval_update_constant(&class_type->default_properties_table[i], (void**)1 TSRMLS_CC); + zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC); } } @@ -1075,7 +1110,7 @@ ZEND_API void zend_update_class_constants(zend_class_e } for (i = 0; i < class_type->default_static_members_count; i++) { - zval_update_constant(&CE_STATIC_MEMBERS(class_type)[i], (void**)1 TSRMLS_CC); + zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i TSRMLS_CC); } *scope = old_scope; @@ -1108,7 +1143,7 @@ ZEND_API void object_properties_init(zend_object *obje /* This function requires 'properties' to contain all props declared in the * class and all props being public. If only a subset is given or the class - * has protected members then you need to merge the properties seperately by + * has protected members then you need to merge the properties separately by * calling zend_merge_properties(). */ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC) /* {{{ */ { @@ -2265,7 +2300,9 @@ void module_destructor(zend_module_entry *module) /* { /* Deinitilaise module globals */ if (module->globals_size) { #ifdef ZTS - ts_free_id(*module->globals_id_ptr); + if (*module->globals_id_ptr) { + ts_free_id(*module->globals_id_ptr); + } #else if (module->globals_dtor) { module->globals_dtor(module->globals_ptr TSRMLS_CC); @@ -2531,6 +2568,9 @@ ZEND_API int zend_disable_function(char *function_name } /* }}} */ +#ifdef ZEND_WIN32 +#pragma optimize("", off) +#endif static zend_object_value display_disabled_class(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { zend_object_value retval; @@ -2539,6 +2579,9 @@ static zend_object_value display_disabled_class(zend_c zend_error(E_WARNING, "%s() has been disabled for security reasons", class_type->name); return retval; } +#ifdef ZEND_WIN32 +#pragma optimize("", on) +#endif /* }}} */ static const zend_function_entry disabled_class_new[] = { @@ -2547,16 +2590,15 @@ static const zend_function_entry disabled_class_new[] ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC) /* {{{ */ { - zend_class_entry disabled_class; + zend_class_entry **disabled_class; zend_str_tolower(class_name, class_name_length); - if (zend_hash_del(CG(class_table), class_name, class_name_length+1)==FAILURE) { + if (zend_hash_find(CG(class_table), class_name, class_name_length+1, (void **)&disabled_class)==FAILURE) { return FAILURE; } - INIT_OVERLOADED_CLASS_ENTRY_EX(disabled_class, class_name, class_name_length, disabled_class_new, NULL, NULL, NULL, NULL, NULL); - disabled_class.create_object = display_disabled_class; - disabled_class.name_length = class_name_length; - zend_register_internal_class(&disabled_class TSRMLS_CC); + INIT_CLASS_ENTRY_INIT_METHODS((**disabled_class), disabled_class_new, NULL, NULL, NULL, NULL, NULL); + (*disabled_class)->create_object = display_disabled_class; + zend_hash_clean(&((*disabled_class)->function_table)); return SUCCESS; } /* }}} */ @@ -2630,7 +2672,6 @@ static int zend_is_callable_check_class(const char *na } /* }}} */ - static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, int strict_class, char **error TSRMLS_DC) /* {{{ */ { zend_class_entry *ce_org = fcc->calling_scope; @@ -2653,11 +2694,9 @@ static int zend_is_callable_check_func(int check_flags /* Skip leading \ */ if (Z_STRVAL_P(callable)[0] == '\\') { mlen = Z_STRLEN_P(callable) - 1; - mname = Z_STRVAL_P(callable) + 1; lmname = zend_str_tolower_dup(Z_STRVAL_P(callable) + 1, mlen); } else { mlen = Z_STRLEN_P(callable); - mname = Z_STRVAL_P(callable); lmname = zend_str_tolower_dup(Z_STRVAL_P(callable), mlen); } /* Check if function with given name exists. @@ -2728,7 +2767,7 @@ static int zend_is_callable_check_func(int check_flags } else if (zend_hash_find(ftable, lmname, mlen+1, (void**)&fcc->function_handler) == SUCCESS) { retval = 1; if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) && - EG(scope) && + !strict_class && EG(scope) && instanceof_function(fcc->function_handler->common.scope, EG(scope) TSRMLS_CC)) { zend_function *priv_fbc; @@ -2809,7 +2848,14 @@ get_function_via_handler: if (retval) { if (fcc->calling_scope && !call_via_handler) { - if (!fcc->object_ptr && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) { + if (!fcc->object_ptr && (fcc->function_handler->common.fn_flags & ZEND_ACC_ABSTRACT)) { + if (error) { + zend_spprintf(error, 0, "cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); + retval = 0; + } else { + zend_error(E_ERROR, "Cannot call abstract method %s::%s()", fcc->calling_scope->name, fcc->function_handler->common.function_name); + } + } else if (!fcc->object_ptr && !(fcc->function_handler->common.fn_flags & ZEND_ACC_STATIC)) { int severity; char *verb; if (fcc->function_handler->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { @@ -3697,6 +3743,8 @@ ZEND_API int zend_update_static_property(zend_class_en (*property)->value = value->value; if (Z_REFCOUNT_P(value) > 0) { zval_copy_ctor(*property); + } else { + efree(value); } } else { zval *garbage = *property; @@ -3862,6 +3910,62 @@ ZEND_API void zend_restore_error_handling(zend_error_h zval_ptr_dtor(&saved->user_handler); } saved->user_handler = NULL; +} +/* }}} */ + +ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len) /* {{{ */ +{ + zend_trait_alias *alias, **alias_ptr; + + alias_ptr = ce->trait_aliases; + alias = *alias_ptr; + while (alias) { + if (alias->alias_len == len && + !strncasecmp(name, alias->alias, alias->alias_len)) { + return alias->alias; + } + alias_ptr++; + alias = *alias_ptr; + } + + return name; +} +/* }}} */ + +ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f) /* {{{ */ +{ + zend_function *func; + HashPosition iterator; + HashTable *function_table; + + if (f->common.type != ZEND_USER_FUNCTION || + *(f->op_array.refcount) < 2 || + !f->common.scope || + !f->common.scope->trait_aliases) { + return f->common.function_name; + } + + function_table = &ce->function_table; + zend_hash_internal_pointer_reset_ex(function_table, &iterator); + while (zend_hash_get_current_data_ex(function_table, (void **)&func, &iterator) == SUCCESS) { + if (func == f) { + char *name; + uint len; + ulong idx; + + if (zend_hash_get_current_key_ex(function_table, &name, &len, &idx, 0, &iterator) != HASH_KEY_IS_STRING) { + return f->common.function_name; + } + --len; + if (len == strlen(f->common.function_name) && + !strncasecmp(name, f->common.function_name, len)) { + return f->common.function_name; + } + return zend_find_alias_name(f->common.scope, name, len); + } + zend_hash_move_forward_ex(function_table, &iterator); + } + return f->common.function_name; } /* }}} */