From: Nikita Popov Date: Mon, 10 Aug 2020 08:08:31 +0000 (+0200) Subject: Fixed bug #79947 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2d087210ebb8adc06dcaca37b9d2dcb93ea2156c;p=php Fixed bug #79947 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. --- diff --git a/NEWS b/NEWS index 0428e1710c..81f9b29251 100644 --- 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 index 0000000000..18d2d75a9d --- /dev/null +++ b/Zend/tests/bug79947.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #79947: Memory leak on invalid offset type in compound assignment +--FILE-- + +--EXPECTF-- +Warning: Illegal offset type in %s on line %d +array(0) { +} diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 59c151fe66..c5b502501e 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 827548504c..a5a2070b43 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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)); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index ae30886c90..6aa34bbd10 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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)); }