diff options
author | Dmitry Stogov <dmitry@php.net> | 2005-06-03 15:36:48 +0000 |
---|---|---|
committer | Dmitry Stogov <dmitry@php.net> | 2005-06-03 15:36:48 +0000 |
commit | 3ba3e35a3e5f6ca000e8be0455ec6a7c7958d5d6 (patch) | |
tree | e8ad058cabfcc6d6a0067fda083919edc1ff02ce | |
parent | 695d12d0db2a7403c29fba2f07e1b6f817381def (diff) | |
download | php-git-3ba3e35a3e5f6ca000e8be0455ec6a7c7958d5d6.tar.gz |
Fixed bug #30394 (Assignment operators yield wrong result with __get/__set)
-rw-r--r-- | NEWS | 2 | ||||
-rwxr-xr-x | Zend/tests/bug30394.phpt | 30 | ||||
-rw-r--r-- | Zend/zend.c | 16 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 14 |
4 files changed, 46 insertions, 16 deletions
@@ -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-- +<?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 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) { |