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:

Developer: laruence@php.net

diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 602b600..75c862d 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -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
-				   greater than 1, classes are always destoyed in reverse order
-				   and trait is declared early than this class */
+
+                *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..cb4dd89 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -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: Wed Apr 16 13:02:46 2014 UTC