]> granicus.if.org Git - php/commitdiff
Fixed bug #30394 (Assignment operators yield wrong result with __get/__set)
authorDmitry Stogov <dmitry@php.net>
Fri, 3 Jun 2005 15:36:48 +0000 (15:36 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 3 Jun 2005 15:36:48 +0000 (15:36 +0000)
NEWS
Zend/tests/bug30394.phpt [new file with mode: 0755]
Zend/zend.c
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index 0edb943636dceb500c994bd6bf333eb60e3b9cac..a22ef11bb2080c84db0c872e9b61dca3d3234a0d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -123,6 +123,8 @@ PHP                                                                        NEWS
 - Fixed bug #30707 (Segmentation fault on exception in method). (Stas, Dmitry)
 - Fixed bug #30702 (cannot initialize class variable from class constant).
   (Dmitry)
+- Fixed bug #30394 (Assignment operators yield wrong result with __get/__set).
+  (Dmitry)
 - Fixed bug #30332 (zend.ze1_compatibility_mode isnt fully compatable with
   array_push()). (Dmitry)
 - Fixed bug #30162 (Catching exception in constructor causes lose of $this).
diff --git a/Zend/tests/bug30394.phpt b/Zend/tests/bug30394.phpt
new file mode 100755 (executable)
index 0000000..b69eda4
--- /dev/null
@@ -0,0 +1,30 @@
+--TEST--
+Bug #30394 (Assignment operators yield wrong result with __get/__set)
+--FILE--
+<?php
+class Container
+{
+       public function __get( $what )
+       {
+               return $this->_p[ $what ];
+       }
+       
+       public function __set( $what, $value )
+       {
+               $this->_p[ $what ] = $value;
+       }
+       
+       private $_p = array();
+}
+
+$c = new Container();
+$c->a = 1;
+$c->a += 1;
+print $c->a;   // --> 2
+
+print " - ";
+$c->a += max( 0, 1 );
+print $c->a;   // --> 4 (!)
+?>
+--EXPECT--
+2 - 3
index 941ccbf44848698b5acafc97196fd2cd944bb695..19373a708bc48ebfc1b06d24f293171e67ae860f 100644 (file)
@@ -879,8 +879,6 @@ ZEND_API void zend_error(int type, const char *format, ...)
        char *error_filename;
        uint error_lineno;
        zval *orig_user_error_handler;
-       zval *orig_garbage[2];
-       int  orig_garbage_ptr;
        TSRMLS_FETCH();
 
        /* Obtain relevant filename and lineno */
@@ -982,12 +980,6 @@ ZEND_API void zend_error(int type, const char *format, ...)
                        orig_user_error_handler = EG(user_error_handler);
                        EG(user_error_handler) = NULL;
            
-                       orig_garbage_ptr = EG(garbage_ptr);
-                       EG(garbage_ptr) = 0;
-                       if (orig_garbage_ptr > 0) {
-                               memcpy(&orig_garbage, &EG(garbage), sizeof(zval*)*orig_garbage_ptr);
-                       }
-
                        if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC)==SUCCESS) {
                                if (retval) {
                                        if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
@@ -1000,14 +992,6 @@ ZEND_API void zend_error(int type, const char *format, ...)
                                zend_error_cb(type, error_filename, error_lineno, format, args);
                        }
 
-                       if (orig_garbage_ptr > 0) {
-                               while (EG(garbage_ptr)) {
-                                       zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
-                               }                               
-                               EG(garbage_ptr) = orig_garbage_ptr;
-                               memcpy(&EG(garbage), &orig_garbage, sizeof(zval*)*orig_garbage_ptr);
-                       }
-
                        if (!EG(user_error_handler)) {
                                EG(user_error_handler) = orig_user_error_handler;
                        } else {
index 9546d869adfef54e7413c7c2e1820bd15cbd9c26..75bb57946b5afc9f0b093bf99aed95779be5cd8c 100644 (file)
@@ -570,6 +570,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
        zend_op_array *original_op_array;
        zend_op **original_opline_ptr;
        zval *orig_free_op1, *orig_free_op2;
+       zval *orig_garbage[2];
+       int  orig_garbage_ptr;
        int (*orig_unary_op)(zval *result, zval *op1);
        int (*orig_binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC);
        zend_class_entry *current_scope;
@@ -862,6 +864,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                orig_free_op2 = EG(free_op2);
                orig_unary_op = EG(unary_op);
                orig_binary_op = EG(binary_op);
+               orig_garbage_ptr = EG(garbage_ptr);
+               EG(garbage_ptr) = 0;
+               if (orig_garbage_ptr > 0) {
+                       memcpy(&orig_garbage, &EG(garbage), sizeof(zval*)*orig_garbage_ptr);
+               }
                zend_execute(EG(active_op_array) TSRMLS_CC);
                if (!fci->symbol_table) {
                        zend_hash_destroy(EG(active_symbol_table));
@@ -875,6 +882,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
                EG(free_op2) = orig_free_op2;
                EG(unary_op) = orig_unary_op;
                EG(binary_op) = orig_binary_op;
+               if (orig_garbage_ptr > 0) {
+                       while (EG(garbage_ptr)) {
+                               zval_ptr_dtor(&EG(garbage)[--EG(garbage_ptr)]);
+                       }                               
+                       EG(garbage_ptr) = orig_garbage_ptr;
+                       memcpy(&EG(garbage), &orig_garbage, sizeof(zval*)*orig_garbage_ptr);
+               }
        } else {
                ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
                if (EX(function_state).function->common.scope) {