summaryrefslogtreecommitdiff
path: root/Zend/zend_object_handlers.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2006-07-26 15:29:27 +0000
committerDmitry Stogov <dmitry@php.net>2006-07-26 15:29:27 +0000
commit30f4d3f9593d3add25510901de3c5811e9a0a2a5 (patch)
tree09526e19e9d5fdba00e1187745ee7d9fae7af641 /Zend/zend_object_handlers.c
parente1dfc4259f636deae6115a344b3d916c63f0f102 (diff)
downloadphp-git-30f4d3f9593d3add25510901de3c5811e9a0a2a5.tar.gz
Fixed bug #38220 (Crash on some object operations)
Diffstat (limited to 'Zend/zend_object_handlers.c')
-rw-r--r--Zend/zend_object_handlers.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index fe6328e157..70e51426fd 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -373,7 +373,6 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
zend_object *zobj;
zval *tmp_member = NULL;
zval **variable_ptr;
- int setter_done = 0;
zend_property_info *property_info;
zobj = Z_OBJ_P(object);
@@ -390,10 +389,8 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC);
if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) {
- if (*variable_ptr == value) {
- /* if we already have this value there, we don't actually need to do anything */
- setter_done = 1;
- } else {
+ /* if we already have this value there, we don't actually need to do anything */
+ if (*variable_ptr != value) {
/* if we are assigning reference, we shouldn't move it, but instead assign variable
to the same pointer */
if (PZVAL_IS_REF(*variable_ptr)) {
@@ -406,10 +403,20 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
zval_copy_ctor(*variable_ptr);
}
zval_dtor(&garbage);
- setter_done = 1;
+ } else {
+ zval *garbage = *variable_ptr;
+
+ /* if we assign referenced variable, we should separate it */
+ value->refcount++;
+ if (PZVAL_IS_REF(value)) {
+ SEPARATE_ZVAL(&value);
+ }
+ *variable_ptr = value;
+ zval_ptr_dtor(&garbage);
}
}
} else {
+ int setter_done = 0;
zend_guard *guard;
if (zobj->ce->__set &&
@@ -422,18 +429,18 @@ static void zend_std_write_property(zval *object, zval *member, zval *value TSRM
setter_done = 1;
guard->in_set = 0;
}
- }
-
- if (!setter_done) {
- zval **foo;
+ if (!setter_done) {
+ zval **foo;
- /* if we assign referenced variable, we should separate it */
- value->refcount++;
- if (PZVAL_IS_REF(value)) {
- SEPARATE_ZVAL(&value);
+ /* if we assign referenced variable, we should separate it */
+ value->refcount++;
+ if (PZVAL_IS_REF(value)) {
+ SEPARATE_ZVAL(&value);
+ }
+ zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void **) &foo);
}
- zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void **) &foo);
}
+
if (tmp_member) {
zval_ptr_dtor(&tmp_member);
}