From 3ba3e35a3e5f6ca000e8be0455ec6a7c7958d5d6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Jun 2005 15:36:48 +0000 Subject: [PATCH] Fixed bug #30394 (Assignment operators yield wrong result with __get/__set) --- NEWS | 2 ++ Zend/tests/bug30394.phpt | 30 ++++++++++++++++++++++++++++++ Zend/zend.c | 16 ---------------- Zend/zend_execute_API.c | 14 ++++++++++++++ 4 files changed, 46 insertions(+), 16 deletions(-) create mode 100755 Zend/tests/bug30394.phpt diff --git a/NEWS b/NEWS index 0edb943636..a22ef11bb2 100644 --- 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 index 0000000000..b69eda4fef --- /dev/null +++ b/Zend/tests/bug30394.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #30394 (Assignment operators yield wrong result with __get/__set) +--FILE-- +_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 diff --git a/Zend/zend.c b/Zend/zend.c index 941ccbf448..19373a708b 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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 { diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9546d869ad..75bb57946b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -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) { -- 2.40.0