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

Reply via email to