From: Antony Dovgal Date: Fri, 16 Sep 2005 17:05:09 +0000 (+0000) Subject: fix #34505 (possible memory corruption when unmangling properties with empty names) X-Git-Tag: php-5.1.0RC2~240 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f43767b249f0bcf05582a75b7024e171f815c5db;p=php fix #34505 (possible memory corruption when unmangling properties with empty names) 1st part --- diff --git a/Zend/zend.c b/Zend/zend.c index 7297cddbd6..3465e55ab6 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -129,7 +129,7 @@ static void print_hash(HashTable *ht, int indent, zend_bool is_object TSRMLS_DC) if (is_object) { char *prop_name, *class_name; - zend_unmangle_property_name(string_key, &class_name, &prop_name); + zend_unmangle_property_name_ex(string_key, str_len, &class_name, &prop_name); ZEND_PUTS(prop_name); if (class_name) { if (class_name[0]=='*') { diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ccadc146de..6b0d3d07c6 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -690,7 +690,7 @@ static void add_class_vars(zend_class_entry *ce, HashTable *properties, zval *re zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos); zend_hash_move_forward_ex(properties, &pos); - zend_unmangle_property_name(key, &class_name, &prop_name); + zend_unmangle_property_name_ex(key, key_len, &class_name, &prop_name); if (class_name) { if (class_name[0] != '*' && strcmp(class_name, ce->name)) { /* filter privates from base classes */ @@ -782,7 +782,7 @@ ZEND_FUNCTION(get_object_vars) (*value)->refcount++; add_assoc_zval_ex(return_value, key, key_len, *value); } else if (instanceof) { - zend_unmangle_property_name(key, &class_name, &prop_name); + zend_unmangle_property_name_ex(key, key_len, &class_name, &prop_name); if (!memcmp(class_name, "*", 2) || (Z_OBJCE_P(EG(This)) == Z_OBJCE_PP(obj) && !strcmp(Z_OBJCE_P(EG(This))->name, class_name))) { /* Not separating references */ (*value)->refcount++; @@ -931,7 +931,7 @@ ZEND_FUNCTION(property_exists) if (property_info->flags & ZEND_ACC_PUBLIC) { RETURN_TRUE; } - zend_unmangle_property_name(property_info->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(property_info->name, property_info->name_length, &class_name, &prop_name); if (!strncmp(class_name, "*", 1)) { if (instanceof_function(EG(scope), ce TSRMLS_CC)) { RETURN_TRUE; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 45e486fc04..a89fb34e74 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2065,7 +2065,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro if (zend_hash_find(&ce->default_static_members, child_info->name, child_info->name_length+1, (void**)&new_prop) == SUCCESS) { if (Z_TYPE_PP(new_prop) != IS_NULL && Z_TYPE_PP(prop) != IS_NULL) { char *prop_name, *tmp; - zend_unmangle_property_name(child_info->name, &tmp, &prop_name); + zend_unmangle_property_name_ex(child_info->name, child_info->name_length, &tmp, &prop_name); zend_error(E_COMPILE_ERROR, "Cannot change initial value of property static protected %s::$%s in class %s", parent_ce->name, prop_name, ce->name); @@ -2814,6 +2814,18 @@ ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, char *src } +ZEND_API void zend_unmangle_property_name_ex(char *mangled_property, int mangled_property_len, char **class_name, char **prop_name) +{ + *prop_name = *class_name = NULL; + + if (mangled_property_len < 2) { /* do not try to unmangle empty strings */ + *prop_name = mangled_property; + return; + } + + zend_unmangle_property_name(mangled_property, class_name, prop_name); +} + ZEND_API void zend_unmangle_property_name(char *mangled_property, char **class_name, char **prop_name) { *prop_name = *class_name = NULL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 006f0eedd8..c9e1bced91 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -522,6 +522,7 @@ void zend_class_add_ref(zend_class_entry **ce); ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length, int internal); ZEND_API void zend_unmangle_property_name(char *mangled_property, char **prop_name, char **class_name); +ZEND_API void zend_unmangle_property_name_ex(char *mangled_property, int mangled_property_len, char **prop_name, char **class_name); #define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor #define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class diff --git a/Zend/zend_reflection_api.c b/Zend/zend_reflection_api.c index 14d0c55d12..2ff4405878 100644 --- a/Zend/zend_reflection_api.c +++ b/Zend/zend_reflection_api.c @@ -720,7 +720,7 @@ static void _property_string(string *str, zend_property_info *prop, char *prop_n string_printf(str, "static "); } - zend_unmangle_property_name(prop->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(prop->name, prop->name_length, &class_name, &prop_name); string_printf(str, "$%s", prop_name); } @@ -978,7 +978,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info property_reference *reference; char *class_name, *prop_name; - zend_unmangle_property_name(prop->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(prop->name, prop->name_length, &class_name, &prop_name); if (!(prop->flags & ZEND_ACC_PRIVATE)) { /* we have to seach the class hierarchy for this (implicit) public or protected property */ @@ -2457,7 +2457,7 @@ ZEND_METHOD(reflection_class, getDefaultProperties) zend_hash_get_current_key_ex(&ce->default_properties, &key, &key_len, &num_index, 0, &pos); zend_hash_move_forward_ex(&ce->default_properties, &pos); - zend_unmangle_property_name(key, &class_name, &prop_name); + zend_unmangle_property_name_ex(key, key_len, &class_name, &prop_name); if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) { /* filter privates from base classes */ continue; @@ -3311,7 +3311,7 @@ ZEND_METHOD(reflection_property, __construct) ZVAL_STRINGL(classname, ce->name, ce->name_length, 1); zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); - zend_unmangle_property_name(property_info->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(property_info->name, property_info->name_length, &class_name, &prop_name); MAKE_STD_ZVAL(propname); ZVAL_STRING(propname, prop_name, 1); zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d0744b309c..eb61bbba6d 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3122,7 +3122,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY) zend_hash_move_forward(fe_ht); } while (key_type != HASH_KEY_IS_STRING || zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS); if (use_key) { - zend_unmangle_property_name(str_key, &class_name, &prop_name); + zend_unmangle_property_name_ex(str_key, str_key_len, &class_name, &prop_name); str_key_len = strlen(prop_name); str_key = estrndup(prop_name, str_key_len); str_key_len++; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index fd20c1fcd6..9d52c39d37 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7598,7 +7598,7 @@ static int ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_hash_move_forward(fe_ht); } while (key_type != HASH_KEY_IS_STRING || zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS); if (use_key) { - zend_unmangle_property_name(str_key, &class_name, &prop_name); + zend_unmangle_property_name_ex(str_key, str_key_len, &class_name, &prop_name); str_key_len = strlen(prop_name); str_key = estrndup(prop_name, str_key_len); str_key_len++; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 14d0c55d12..2ff4405878 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -720,7 +720,7 @@ static void _property_string(string *str, zend_property_info *prop, char *prop_n string_printf(str, "static "); } - zend_unmangle_property_name(prop->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(prop->name, prop->name_length, &class_name, &prop_name); string_printf(str, "$%s", prop_name); } @@ -978,7 +978,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info property_reference *reference; char *class_name, *prop_name; - zend_unmangle_property_name(prop->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(prop->name, prop->name_length, &class_name, &prop_name); if (!(prop->flags & ZEND_ACC_PRIVATE)) { /* we have to seach the class hierarchy for this (implicit) public or protected property */ @@ -2457,7 +2457,7 @@ ZEND_METHOD(reflection_class, getDefaultProperties) zend_hash_get_current_key_ex(&ce->default_properties, &key, &key_len, &num_index, 0, &pos); zend_hash_move_forward_ex(&ce->default_properties, &pos); - zend_unmangle_property_name(key, &class_name, &prop_name); + zend_unmangle_property_name_ex(key, key_len, &class_name, &prop_name); if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) { /* filter privates from base classes */ continue; @@ -3311,7 +3311,7 @@ ZEND_METHOD(reflection_property, __construct) ZVAL_STRINGL(classname, ce->name, ce->name_length, 1); zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); - zend_unmangle_property_name(property_info->name, &class_name, &prop_name); + zend_unmangle_property_name_ex(property_info->name, property_info->name_length, &class_name, &prop_name); MAKE_STD_ZVAL(propname); ZVAL_STRING(propname, prop_name, 1); zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL);