]> granicus.if.org Git - php/commitdiff
Fixed bug #30889 (Conflict between __get/__set and ++ operator)
authorDmitry Stogov <dmitry@php.net>
Tue, 26 Apr 2005 13:23:08 +0000 (13:23 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 26 Apr 2005 13:23:08 +0000 (13:23 +0000)
NEWS
Zend/tests/bug30889.phpt [new file with mode: 0644]
Zend/zend_execute.c

diff --git a/NEWS b/NEWS
index ff4a6fa36eee4b6516f6eecbe7aecf36a9f99ee6..86b5cb3b728eff198fccaad840006e1a6f7578d6 100644 (file)
--- 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 (file)
index 0000000..4f58cbf
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+Bug #30889 Conflict between __get/__set and ++ operator
+--FILE--
+<?php
+class overloaded
+{
+  private $values;
+  function __construct()
+  {
+    $this->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)
index db2fe20bc5a56d4a7c09caf433fc578f72da6633..3a26ae9d7120acb501ca3e9858fd2da290eef30f 100644 (file)
@@ -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);
        }