laruence Mon, 19 Dec 2011 16:48:18 +0000 Revision: http://svn.php.net/viewvc?view=revision&revision=321166
Log: Fixed bug #60558 (Invalid read and writes) Re-Fixed bug #60536 (Traits Segfault) #Thanks to tony2001, I found the previous fix -r321089 is actually not a correct one. #The key problem there is because the traits didn't correct set the property_info.offset #for private properties. so here come the new fix. Bugs: https://bugs.php.net/60558 (Re-Opened) Invalid read and writes https://bugs.php.net/60536 (Closed) Traits Segfault Changed paths: U php/php-src/branches/PHP_5_4/NEWS U php/php-src/branches/PHP_5_4/Zend/zend_compile.c U php/php-src/branches/PHP_5_4/Zend/zend_object_handlers.c U php/php-src/trunk/Zend/zend_compile.c U php/php-src/trunk/Zend/zend_object_handlers.c
Modified: php/php-src/branches/PHP_5_4/NEWS =================================================================== --- php/php-src/branches/PHP_5_4/NEWS 2011-12-19 16:14:50 UTC (rev 321165) +++ php/php-src/branches/PHP_5_4/NEWS 2011-12-19 16:48:18 UTC (rev 321166) @@ -7,6 +7,7 @@ . Fixed bug #60536 (Traits Segfault). (Laruence) . Fixed bug #60362 (non-existent sub-sub keys should not have values). (Laruence, alan_k, Stas) + . Fixed bug #60558 (Invalid read and writes). (Laruence) - CLI SAPI: . Fixed bug #60477 (Segfault after two multipart/form-data POST requests, Modified: php/php-src/branches/PHP_5_4/Zend/zend_compile.c =================================================================== --- php/php-src/branches/PHP_5_4/Zend/zend_compile.c 2011-12-19 16:14:50 UTC (rev 321165) +++ php/php-src/branches/PHP_5_4/Zend/zend_compile.c 2011-12-19 16:48:18 UTC (rev 321166) @@ -4208,6 +4208,50 @@ } /* }}} */ +static void zend_traits_register_private_property(zend_class_entry *ce, const char *name, int name_len, zend_property_info *old_info, zval *property TSRMLS_DC) /* {{{ */ +{ + char *priv_name; + int priv_name_length; + const char *interned_name; + zend_property_info property_info; + ulong h = zend_get_hash_value(name, name_len+1); + property_info = *old_info; + + if (old_info->flags & ZEND_ACC_STATIC) { + property_info.offset = ce->default_static_members_count++; + ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS); + ce->default_static_members_table[property_info.offset] = property; + if (ce->type == ZEND_USER_CLASS) { + ce->static_members_table = ce->default_static_members_table; + } + } else { + property_info.offset = ce->default_properties_count++; + ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS); + ce->default_properties_table[property_info.offset] = property; + } + + zend_mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_len, ce->type & ZEND_INTERNAL_CLASS); + property_info.name = priv_name; + property_info.name_length = priv_name_length; + + interned_name = zend_new_interned_string(property_info.name, property_info.name_length+1, 0 TSRMLS_CC); + if (interned_name != property_info.name) { + if (ce->type == ZEND_USER_CLASS) { + efree((char*)property_info.name); + } else { + free((char*)property_info.name); + } + property_info.name = interned_name; + } + + property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1); + + property_info.ce = ce; + + zend_hash_quick_update(&ce->properties_info, name, name_len+1, h, &property_info, sizeof(zend_property_info), NULL); +} +/* }}} */ + static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */ { size_t i; @@ -4295,6 +4339,17 @@ prop_name, ce->name); } + } else { + /* private property, make the property_info.offset indenpended */ + if (property_info->flags & ZEND_ACC_STATIC) { + prop_value = ce->traits[i]->default_static_members_table[property_info->offset]; + } else { + prop_value = ce->traits[i]->default_properties_table[property_info->offset]; + } + Z_ADDREF_P(prop_value); + + zend_traits_register_private_property(ce, prop_name, prop_name_length, property_info, prop_value TSRMLS_CC); + return; } } Modified: php/php-src/branches/PHP_5_4/Zend/zend_object_handlers.c =================================================================== --- php/php-src/branches/PHP_5_4/Zend/zend_object_handlers.c 2011-12-19 16:14:50 UTC (rev 321165) +++ php/php-src/branches/PHP_5_4/Zend/zend_object_handlers.c 2011-12-19 16:48:18 UTC (rev 321166) @@ -62,7 +62,6 @@ ALLOC_HASHTABLE(zobj->properties); zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0); if (ce->default_properties_count) { - char *flags = ecalloc(ce->default_properties_count, sizeof(char)); 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)) { @@ -71,7 +70,6 @@ prop_info->offset >= 0 && zobj->properties_table[prop_info->offset]) { zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - flags[prop_info->offset] = 1; } } while (ce->parent && ce->parent->default_properties_count) { @@ -84,15 +82,10 @@ (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && prop_info->offset >= 0 && zobj->properties_table[prop_info->offset]) { - if (UNEXPECTED(flags[prop_info->offset])) { - zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - } else { - zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - } + zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); } } } - efree(flags); } } } Modified: php/php-src/trunk/Zend/zend_compile.c =================================================================== --- php/php-src/trunk/Zend/zend_compile.c 2011-12-19 16:14:50 UTC (rev 321165) +++ php/php-src/trunk/Zend/zend_compile.c 2011-12-19 16:48:18 UTC (rev 321166) @@ -4208,6 +4208,50 @@ } /* }}} */ +static void zend_traits_register_private_property(zend_class_entry *ce, const char *name, int name_len, zend_property_info *old_info, zval *property TSRMLS_DC) /* {{{ */ +{ + char *priv_name; + int priv_name_length; + const char *interned_name; + zend_property_info property_info; + ulong h = zend_get_hash_value(name, name_len+1); + property_info = *old_info; + + if (old_info->flags & ZEND_ACC_STATIC) { + property_info.offset = ce->default_static_members_count++; + ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS); + ce->default_static_members_table[property_info.offset] = property; + if (ce->type == ZEND_USER_CLASS) { + ce->static_members_table = ce->default_static_members_table; + } + } else { + property_info.offset = ce->default_properties_count++; + ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS); + ce->default_properties_table[property_info.offset] = property; + } + + zend_mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_len, ce->type & ZEND_INTERNAL_CLASS); + property_info.name = priv_name; + property_info.name_length = priv_name_length; + + interned_name = zend_new_interned_string(property_info.name, property_info.name_length+1, 0 TSRMLS_CC); + if (interned_name != property_info.name) { + if (ce->type == ZEND_USER_CLASS) { + efree((char*)property_info.name); + } else { + free((char*)property_info.name); + } + property_info.name = interned_name; + } + + property_info.h = zend_get_hash_value(property_info.name, property_info.name_length+1); + + property_info.ce = ce; + + zend_hash_quick_update(&ce->properties_info, name, name_len+1, h, &property_info, sizeof(zend_property_info), NULL); +} +/* }}} */ + static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {{{ */ { size_t i; @@ -4295,6 +4339,17 @@ prop_name, ce->name); } + } else { + /* private property, make the property_info.offset indenpended */ + if (property_info->flags & ZEND_ACC_STATIC) { + prop_value = ce->traits[i]->default_static_members_table[property_info->offset]; + } else { + prop_value = ce->traits[i]->default_properties_table[property_info->offset]; + } + Z_ADDREF_P(prop_value); + + zend_traits_register_private_property(ce, prop_name, prop_name_length, property_info, prop_value TSRMLS_CC); + return; } } Modified: php/php-src/trunk/Zend/zend_object_handlers.c =================================================================== --- php/php-src/trunk/Zend/zend_object_handlers.c 2011-12-19 16:14:50 UTC (rev 321165) +++ php/php-src/trunk/Zend/zend_object_handlers.c 2011-12-19 16:48:18 UTC (rev 321166) @@ -62,7 +62,6 @@ ALLOC_HASHTABLE(zobj->properties); zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0); if (ce->default_properties_count) { - char *flags = ecalloc(ce->default_properties_count, sizeof(char)); 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)) { @@ -71,7 +70,6 @@ prop_info->offset >= 0 && zobj->properties_table[prop_info->offset]) { zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - flags[prop_info->offset] = 1; } } while (ce->parent && ce->parent->default_properties_count) { @@ -84,15 +82,10 @@ (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && prop_info->offset >= 0 && zobj->properties_table[prop_info->offset]) { - if (UNEXPECTED(flags[prop_info->offset])) { - zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - } else { - zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); - } + zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); } } } - efree(flags); } } }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php