]> granicus.if.org Git - php/commitdiff
Fixed bug #79947
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 08:08:31 +0000 (10:08 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Aug 2020 08:11:56 +0000 (10:11 +0200)
Move the FREE_OP for op_data out of the zend_binary_assign_op_dim_slow()
slow path, so it can be used by the other error path as well. This
makes ASSIGN_DIM_OP structurally more similar to ASSIGN_DIM.

NEWS
Zend/tests/bug79947.phpt [new file with mode: 0644]
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 0428e1710cf7b60b086c64e6d9877ceea2aa9bbf..81f9b29251a28d9735949d07f20fced5237c889b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP                                                                        NEWS
   . Fixed bug #79919 (Stack use-after-scope in define()). (cmb)
   . Fixed bug #79934 (CRLF-only line in heredoc causes parsing error).
     (Pieter van den Ham)
+  . Fixed bug #79947 (Memory leak on invalid offset type in compound
+    assignment). (Nikita)
 
 - Gettext:
   . Fixed bug #70574 (Tests fail due to relying on Linux fallback behavior for
diff --git a/Zend/tests/bug79947.phpt b/Zend/tests/bug79947.phpt
new file mode 100644 (file)
index 0000000..18d2d75
--- /dev/null
@@ -0,0 +1,13 @@
+--TEST--
+Bug #79947: Memory leak on invalid offset type in compound assignment
+--FILE--
+<?php
+$array = [];
+$key = [];
+$array[$key] += [$key];
+var_dump($array);
+?>
+--EXPECTF--
+Warning: Illegal offset type in %s on line %d
+array(0) {
+}
index 59c151fe66ed0a565ecc5fb0e33b7306fabc2c6a..c5b502501e7d5dc9aef54590114dfa9494d32054 100644 (file)
@@ -2051,8 +2051,6 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
 
 static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC)
 {
-       zend_free_op free_op_data1;
-
        if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
                if (opline->op2_type == IS_UNUSED) {
                        zend_use_new_element_for_string();
@@ -2063,8 +2061,6 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
        } else if (EXPECTED(!Z_ISERROR_P(container))) {
                zend_use_scalar_as_array();
        }
-       get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
-       FREE_OP(free_op_data1);
 }
 
 static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC)
index 827548504cc291115577ae62afc9e6aff69f6b4b..a5a2070b437b230581fac677523ff5a02c004e08 100644 (file)
@@ -1272,6 +1272,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 ZEND_VM_C_LABEL(assign_dim_op_ret_null):
+                       FREE_UNFETCHED_OP_DATA();
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
index ae30886c9056d87784c2fb4ec1c1c19b471a2f7d..6aa34bbd1094f83f295f0f40a23e6d7e2dc5ff11 100644 (file)
@@ -22205,6 +22205,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -24494,6 +24495,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -26898,6 +26900,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -28172,6 +28175,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -39120,6 +39124,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -42619,6 +42624,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -45599,6 +45605,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }
@@ -47701,6 +47708,7 @@ assign_dim_op_new_array:
                } else {
                        zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
 assign_dim_op_ret_null:
+                       FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
                        if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
                                ZVAL_NULL(EX_VAR(opline->result.var));
                        }