diff options
author | Dmitry Stogov <dmitry@php.net> | 2006-07-26 15:29:27 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2006-07-26 15:29:27 +0000 |
commit | 30f4d3f9593d3add25510901de3c5811e9a0a2a5 (patch) | |
tree | 09526e19e9d5fdba00e1187745ee7d9fae7af641 /Zend/zend_object_handlers.c | |
parent | e1dfc4259f636deae6115a344b3d916c63f0f102 (diff) | |
download | php-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.c | 37 |
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); } |