]> granicus.if.org Git - php/commitdiff
Fix one issue reported in bug #77310
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 7 Jan 2019 08:58:59 +0000 (09:58 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 7 Jan 2019 09:05:23 +0000 (10:05 +0100)
SCCP did not handle array ASSIGN_* with a BOT operand correctly.

ext/opcache/Optimizer/sccp.c
ext/opcache/tests/bug77310_1.phpt [new file with mode: 0644]

index 4cafa76eb4c79854b7bf933cd6886e695fa3f466..c224e4afcc88398417a0e8346d8136e019fb8d16 100644 (file)
@@ -1401,19 +1401,24 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                                                if (IS_BOT(data)) {
                                                        dup_partial_array(&zv, op1);
                                                        ct_eval_del_array_elem(&zv, op2);
+                                                       SET_RESULT_BOT(result);
+                                                       SET_RESULT(op1, &zv);
+                                                       zval_ptr_dtor_nogc(&tmp);
+                                                       zval_ptr_dtor_nogc(&zv);
+                                                       break;
+                                               }
+
+                                               if (zend_optimizer_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
+                                                       SET_RESULT_BOT(result);
+                                                       SET_RESULT_BOT(op1);
+                                                       zval_ptr_dtor_nogc(&tmp);
+                                                       break;
+                                               }
+
+                                               if (IS_PARTIAL_ARRAY(op1)) {
+                                                       dup_partial_array(&zv, op1);
                                                } else {
-                                                       if (zend_optimizer_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
-                                                               SET_RESULT_BOT(result);
-                                                               SET_RESULT_BOT(op1);
-                                                               zval_ptr_dtor_nogc(&tmp);
-                                                               break;
-                                                       }
-
-                                                       if (IS_PARTIAL_ARRAY(op1)) {
-                                                               dup_partial_array(&zv, op1);
-                                                       } else {
-                                                               ZVAL_COPY(&zv, op1);
-                                                       }
+                                                       ZVAL_COPY(&zv, op1);
                                                }
 
                                                if (ct_eval_assign_dim(&zv, &tmp, op2) == SUCCESS) {
@@ -1423,6 +1428,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                                                        zval_ptr_dtor_nogc(&zv);
                                                        break;
                                                }
+
                                                zval_ptr_dtor_nogc(&tmp);
                                                zval_ptr_dtor_nogc(&zv);
                                        }
@@ -1440,17 +1446,22 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                                                if (IS_BOT(data)) {
                                                        dup_partial_object(&zv, op1);
                                                        ct_eval_del_obj_prop(&zv, op2);
-                                               } else {
-                                                       if (zend_optimizer_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
-                                                               SET_RESULT_BOT(result);
-                                                               SET_RESULT_BOT(op1);
-                                                               zval_ptr_dtor_nogc(&tmp);
-                                                               break;
-                                                       }
+                                                       SET_RESULT_BOT(result);
+                                                       SET_RESULT(op1, &zv);
+                                                       zval_ptr_dtor_nogc(&tmp);
+                                                       zval_ptr_dtor_nogc(&zv);
+                                                       break;
+                                               }
 
-                                                       dup_partial_object(&zv, op1);
+                                               if (zend_optimizer_eval_binary_op(&tmp, zend_compound_assign_to_binary_op(opline->opcode), &tmp, data) != SUCCESS) {
+                                                       SET_RESULT_BOT(result);
+                                                       SET_RESULT_BOT(op1);
+                                                       zval_ptr_dtor_nogc(&tmp);
+                                                       break;
                                                }
 
+                                               dup_partial_object(&zv, op1);
+
                                                if (ct_eval_assign_obj(&zv, &tmp, op2) == SUCCESS) {
                                                        SET_RESULT(result, &tmp);
                                                        SET_RESULT(op1, &zv);
@@ -1458,6 +1469,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
                                                        zval_ptr_dtor_nogc(&zv);
                                                        break;
                                                }
+
                                                zval_ptr_dtor_nogc(&tmp);
                                                zval_ptr_dtor_nogc(&zv);
                                        }
diff --git a/ext/opcache/tests/bug77310_1.phpt b/ext/opcache/tests/bug77310_1.phpt
new file mode 100644 (file)
index 0000000..f7baec7
--- /dev/null
@@ -0,0 +1,19 @@
+--TEST--
+Bug #77310 (1): Incorrect SCCP for compound assign to arrays
+--FILE--
+<?php
+
+function breakit($data_arr) {
+    $foo[0] = "";
+    for ($i = 0; $i < count($data_arr); $i++) {
+        $foo[0] .= $data_arr[$i];
+    }
+    echo $foo[0] . "\n";
+}
+
+$data = ['zero', 'one', 'two'];
+breakit($data);
+
+?>
+--EXPECT--
+zeroonetwo