From: Dmitry Stogov Date: Mon, 21 May 2012 09:57:41 +0000 (+0400) Subject: Fixed bug #61998 (Using traits with method aliases appears to result in crash during... X-Git-Tag: php-5.4.4RC2~55 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ae8d2fbfb8797b1038ad64c267ee0797f977671;p=php Fixed bug #61998 (Using traits with method aliases appears to result in crash during execution) --- diff --git a/NEWS b/NEWS index 1a87234b67..68f0a3563a 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,8 @@ PHP NEWS . Fixed missing bound check in iptcparse(). (chris at chiappa.net) . Fixed bug #62005 (unexpected behavior when incrementally assigning to a member of a null object). (Laruence) + . Fixed bug #61998 (Using traits with method aliases appears to result in + crash during execution). (Dmitry) . Fixed bug #61978 (Object recursion not detected for classes that implement JsonSerializable). (Felipe) . Fixed bug #61991 (long overflow in realpath_cache_get()). (Anatoliy) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 602b600410..b7e7cd3bbb 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3619,6 +3619,7 @@ ZEND_API void zend_do_implement_trait(zend_class_entry *ce, zend_class_entry *tr } } ce->traits[ce->num_traits++] = trait; + trait->refcount++; } } /* }}} */ @@ -3870,8 +3871,8 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args, fn_copy = *fn; function_add_ref(&fn_copy); /* this function_name is never destroyed, because its refcount - greater than 1, classes are always destoyed in reverse order - and trait is declared early than this class */ + greater than 1 and classes are always destoyed before the + traits they use */ fn_copy.common.function_name = aliases[i]->alias; /* if it is 0, no modifieres has been changed */ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 65fa85185e..19fd71e763 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -215,6 +215,12 @@ ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC) void _destroy_zend_class_traits_info(zend_class_entry *ce) { if (ce->num_traits > 0 && ce->traits) { + size_t i; + for (i = 0; i < ce->num_traits; i++) { + if (ce->traits[i]) { + destroy_zend_class(&ce->traits[i]); + } + } efree(ce->traits); }