summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2011-12-16 19:02:52 +0000
committerXinchen Hui <laruence@php.net>2011-12-16 19:02:52 +0000
commit01dc47631ea044f0df75a1e59d1313ca96a6ba66 (patch)
tree17dd30b7377da159d419889c4663c233361dc82f /Zend/zend_object_handlers.c
parente467a791d3111438ea1160c22b986d24bd09450e (diff)
downloadphp-git-01dc47631ea044f0df75a1e59d1313ca96a6ba66.tar.gz
Fixed bug #60536 (Traits Segfault)
# this is a tough one, I think I should explain # Zend use zend_object->properties_table both as zval ** and zval *** # if a zend_object->properties is not initialized, the properties_table is zval ** # while in rebuild_object_properties, zend will store the zval ** to zend_object->properties # then stash the zval ***(ie, zobj->properties_table[0] is zval ** now) to zobj->properties_table[0] # so when a zend_object inherit form multi parent and these parent have a same property_info->offset # properties, will result in a repeat zval **->zval ** transform, which will lead to a segmentfault # *may be* this fix is not the best fix, we should not use this tricky way, and rewrite this mechanism.
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index b43021dd22..be04bf3565 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -62,6 +62,7 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
ALLOC_HASHTABLE(zobj->properties);
zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
if (ce->default_properties_count) {
+ int *flags = ecalloc(ce->default_properties_count, sizeof(int));
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)) {
@@ -70,6 +71,7 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
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) {
@@ -81,11 +83,16 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
(prop_info->flags & ZEND_ACC_STATIC) == 0 &&
(prop_info->flags & ZEND_ACC_PRIVATE) != 0 &&
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]);
+ 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]);
+ }
}
}
}
+ efree(flags);
}
}
}