]> granicus.if.org Git - php/commitdiff
Fixed behavior of failing compound assignments (they shouldn't change the source...
authorDmitry Stogov <dmitry@zend.com>
Fri, 2 Dec 2016 12:13:55 +0000 (15:13 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 2 Dec 2016 12:13:55 +0000 (15:13 +0300)
Zend/tests/compound_assign_failure.phpt
Zend/zend_operators.c

index f1afc783a0efa214d1455c48d9d96c238350d421..f8d863106a57d076f5b14a149e7e33a28174b045 100644 (file)
@@ -1,5 +1,7 @@
 --TEST--
 Behavior of failing compound assignment
+--INI--
+opcache.optimization_level=0
 --FILE--
 <?php
 
@@ -17,8 +19,23 @@ try {
        $a = 1;
        $a <<= -1;
 } catch (Error $e) { var_dump($a); }
+
+set_error_handler(function() { throw new Exception; });
+
+try {
+       $a = [];
+       $a .= "foo";
+} catch (Throwable $e) { var_dump($a); }
+
+try {
+       $a = "foo";
+       $a .= [];
+} catch (Throwable $e) { var_dump($a); }
 ?>
 --EXPECT--
 int(1)
 int(1)
 int(1)
+array(0) {
+}
+string(3) "foo"
index 0d3c8e46e7e2a9d2cbaef5565c07aa591317ec2e..96571da53edba09934c540c20843083c711d8b75 100644 (file)
@@ -1628,6 +1628,10 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
                        ZEND_TRY_BINARY_OBJECT_OPERATION(ZEND_CONCAT, concat_function);
                        use_copy1 = zend_make_printable_zval(op1, &op1_copy);
                        if (use_copy1) {
+                               if (UNEXPECTED(EG(exception))) {
+                                       zval_dtor(&op1_copy);
+                                       return FAILURE;
+                               }
                                if (result == op1) {
                                        if (UNEXPECTED(op1 == op2)) {
                                                op2 = &op1_copy;
@@ -1646,6 +1650,13 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
                        ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_CONCAT);
                        use_copy2 = zend_make_printable_zval(op2, &op2_copy);
                        if (use_copy2) {
+                               if (UNEXPECTED(EG(exception))) {
+                                       if (UNEXPECTED(use_copy1)) {
+                                               zval_dtor(op1);
+                                       }
+                                       zval_dtor(&op2_copy);
+                                       return FAILURE;
+                               }
                                op2 = &op2_copy;
                        }
                }