summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2005-06-03 15:36:48 +0000
committerDmitry Stogov <dmitry@php.net>2005-06-03 15:36:48 +0000
commit3ba3e35a3e5f6ca000e8be0455ec6a7c7958d5d6 (patch)
treee8ad058cabfcc6d6a0067fda083919edc1ff02ce
parent695d12d0db2a7403c29fba2f07e1b6f817381def (diff)
downloadphp-git-3ba3e35a3e5f6ca000e8be0455ec6a7c7958d5d6.tar.gz
Fixed bug #30394 (Assignment operators yield wrong result with __get/__set)
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug30394.phpt30
-rw-r--r--Zend/zend.c16
-rw-r--r--Zend/zend_execute_API.c14
4 files changed, 46 insertions, 16 deletions
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--
+<?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) {