From: Dmitry Stogov Date: Tue, 26 Apr 2005 13:23:08 +0000 (+0000) Subject: Fixed bug #30889 (Conflict between __get/__set and ++ operator) X-Git-Tag: php-5.0.5RC1~371 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=519642125f5af5629e8880ca12208612e926fdf2;p=php Fixed bug #30889 (Conflict between __get/__set and ++ operator) --- diff --git a/NEWS b/NEWS index ff4a6fa36e..86b5cb3b72 100644 --- a/NEWS +++ b/NEWS @@ -50,6 +50,7 @@ PHP NEWS - Fixed bug #31502 (Wrong deserialization from session when using WDDX serializer). (Dmitry) - Fixed bug #31363 (broken non-blocking flock()). ian at snork dot net +- Fixed bug #30889 (Conflict between __get/__set and ++ operator). (Dmitry) - Fixed bug #30833 (array_count_values() modifying input array). (Tony) - Fixed bug #30819 (Better support for LDAP SASL bind). (Jani) - Fixed bug #30702 (cannot initialize class variable from class constant). diff --git a/Zend/tests/bug30889.phpt b/Zend/tests/bug30889.phpt new file mode 100644 index 0000000000..4f58cbf5a5 --- /dev/null +++ b/Zend/tests/bug30889.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #30889 Conflict between __get/__set and ++ operator +--FILE-- +values = array('a' => 0); + } + function __set($name, $value) + { + print "set $name = $value ($name was ".$this->values[$name].")\n"; + $this->values[$name] = $value; + } + function __get($name) + { + print "get $name (returns ".$this->values[$name].")\n"; + return $this->values[$name]; + } +} +$test = new overloaded(); +$test->a++; // __get(), then __set() +++$test->a; +?> +--EXPECT-- +get a (returns 0) +set a = 1 (a was 0) +get a (returns 1) +set a = 2 (a was 1) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index db2fe20bc5..3a26ae9d71 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1270,6 +1270,7 @@ static void zend_post_incdec_property(znode *result, znode *op1, znode *op2, tem if (!have_get_ptr) { zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_RW TSRMLS_CC); + zval *z_copy; if (z->type == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval *value = Z_OBJ_HT_P(z)->get(z TSRMLS_CC); @@ -1282,9 +1283,14 @@ static void zend_post_incdec_property(znode *result, znode *op1, znode *op2, tem } *retval = *z; zendi_zval_copy_ctor(*retval); - incdec_op(z); + ALLOC_ZVAL(z_copy); + *z_copy = *z; + zendi_zval_copy_ctor(*z_copy); + INIT_PZVAL(z_copy); + incdec_op(z_copy); z->refcount++; - Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC); + Z_OBJ_HT_P(object)->write_property(object, property, z_copy TSRMLS_CC); + zval_ptr_dtor(&z_copy); zval_ptr_dtor(&z); }