php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #61998
Patch bug61998.patch revision 2012-05-21 08:30 UTC by dmitry at zend dot com
revision 2012-05-19 06:16 UTC by laruence@php.net
Patch bug61998.phpt revision 2012-05-19 06:17 UTC by laruence@php.net

Patch bug61998.patch for Reproducible crash Bug #61998

Patch version 2012-05-19 06:16 UTC

Return to Bug #61998 | Download this patch
This patch is obsolete

Obsoleted by patches:

Patch Revisions: 2012-05-21 08:30 UTC | 2012-05-19 06:16 UTC

Developer: laruence@php.net



  diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
 index 602b600..b7e7cd3 100644
 index 602b600..75c862d 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,
 @@ -3867,11 +3867,15 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
  				&& (!aliases[i]->trait_method->ce || fn->common.scope == aliases[i]->trait_method->ce)
  				&& aliases[i]->trait_method->mname_len == fnname_len
  				&& (zend_binary_strcasecmp(aliases[i]->trait_method->method_name, aliases[i]->trait_method->mname_len, fn->common.function_name, fnname_len) == 0)) {
 +                zend_function *fn_copy_p = (zend_function *)emalloc(sizeof(zend_function));
 +
   				fn_copy = *fn;
   				function_add_ref(&fn_copy);
  				/* this function_name is never destroyed, because its refcount
 -				/* 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_p = *fn;
 +                aliases[i]->function = fn_copy_p;
 +                function_add_ref(fn_copy_p);
 +				/* we have ensured this function_name will never be destroyed before alias info is destroyed */
   				fn_copy.common.function_name = aliases[i]->alias;
   					
   				/* if it is 0, no modifieres has been changed */
 @@ -4076,14 +4080,14 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
  	size_t i;
  
  	/* prepare copies of trait function tables for combination */
 -	function_tables = malloc(sizeof(HashTable*) * ce->num_traits);
 -	resulting_table = (HashTable *) malloc(sizeof(HashTable));
 +	function_tables = emalloc(sizeof(HashTable*) * ce->num_traits);
 +	resulting_table = (HashTable *)emalloc(sizeof(HashTable));
  	
  	/* TODO: revisit this start size, may be its not optimal */
 -	zend_hash_init_ex(resulting_table, 10, NULL, NULL, 1, 0);
 +	zend_hash_init_ex(resulting_table, 10, NULL, NULL, 0, 0);
    
  	for (i = 0; i < ce->num_traits; i++) {
 -		function_tables[i] = (HashTable *) malloc(sizeof(HashTable));
 +		function_tables[i] = (HashTable *)emalloc(sizeof(HashTable));
  		zend_hash_init_ex(function_tables[i], ce->traits[i]->function_table.nNumOfElements, NULL, NULL, 1, 0);
  
  		if (ce->trait_precedences) {
 @@ -4116,14 +4120,14 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
  	for (i = 0; i < ce->num_traits; i++) {
  		/* zend_hash_destroy(function_tables[i]); */
  		zend_hash_graceful_destroy(function_tables[i]);
 -		free(function_tables[i]);
 +		efree(function_tables[i]);
  	}
 -	free(function_tables);
 +	efree(function_tables);
  
  	/* free temporary resulting table */
  	/* zend_hash_destroy(resulting_table); */
  	zend_hash_graceful_destroy(resulting_table);
 -	free(resulting_table);
 +	efree(resulting_table);
  }
  /* }}} */
  
  diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
 index 65fa851..2d76f6c 100644
 index 65fa851..cb4dd89 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);
  	}
  	
 @@ -230,6 +230,11 @@ void _destroy_zend_class_traits_info(zend_class_entry *ce)
  				}
  				efree(ce->trait_aliases[i]->trait_method);
  			}
 +
 +            if (ce->trait_aliases[i]->function) {
 +                zend_function_dtor(ce->trait_aliases[i]->function);
 +                efree(ce->trait_aliases[i]->function);
 +            }
  			
  			if (ce->trait_aliases[i]->alias) {
  				efree((char*)ce->trait_aliases[i]->alias);
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 08:02:55 2014 UTC