Skip to content

Commit 2d08721

Browse files
committed
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.
1 parent fa9bd81 commit 2d08721

File tree

5 files changed

+24
-4
lines changed

5 files changed

+24
-4
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ PHP NEWS
1111
. Fixed bug #79919 (Stack use-after-scope in define()). (cmb)
1212
. Fixed bug #79934 (CRLF-only line in heredoc causes parsing error).
1313
(Pieter van den Ham)
14+
. Fixed bug #79947 (Memory leak on invalid offset type in compound
15+
assignment). (Nikita)
1416

1517
- Gettext:
1618
. Fixed bug #70574 (Tests fail due to relying on Linux fallback behavior for

Zend/tests/bug79947.phpt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
Bug #79947: Memory leak on invalid offset type in compound assignment
3+
--FILE--
4+
<?php
5+
$array = [];
6+
$key = [];
7+
$array[$key] += [$key];
8+
var_dump($array);
9+
?>
10+
--EXPECTF--
11+
Warning: Illegal offset type in %s on line %d
12+
array(0) {
13+
}

Zend/zend_execute.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,8 +2051,6 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s
20512051

20522052
static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC)
20532053
{
2054-
zend_free_op free_op_data1;
2055-
20562054
if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
20572055
if (opline->op2_type == IS_UNUSED) {
20582056
zend_use_new_element_for_string();
@@ -2063,8 +2061,6 @@ static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim
20632061
} else if (EXPECTED(!Z_ISERROR_P(container))) {
20642062
zend_use_scalar_as_array();
20652063
}
2066-
get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1, &free_op_data1);
2067-
FREE_OP(free_op_data1);
20682064
}
20692065

20702066
static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval *dim, zend_value *value EXECUTE_DATA_DC)

Zend/zend_vm_def.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12721272
} else {
12731273
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
12741274
ZEND_VM_C_LABEL(assign_dim_op_ret_null):
1275+
FREE_UNFETCHED_OP_DATA();
12751276
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
12761277
ZVAL_NULL(EX_VAR(opline->result.var));
12771278
}

Zend/zend_vm_execute.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22205,6 +22205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H
2220522205
} else {
2220622206
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
2220722207
assign_dim_op_ret_null:
22208+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
2220822209
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2220922210
ZVAL_NULL(EX_VAR(opline->result.var));
2221022211
}
@@ -24494,6 +24495,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_
2449424495
} else {
2449524496
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
2449624497
assign_dim_op_ret_null:
24498+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
2449724499
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2449824500
ZVAL_NULL(EX_VAR(opline->result.var));
2449924501
}
@@ -26898,6 +26900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_
2689826900
} else {
2689926901
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
2690026902
assign_dim_op_ret_null:
26903+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
2690126904
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2690226905
ZVAL_NULL(EX_VAR(opline->result.var));
2690326906
}
@@ -28172,6 +28175,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND
2817228175
} else {
2817328176
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
2817428177
assign_dim_op_ret_null:
28178+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
2817528179
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
2817628180
ZVAL_NULL(EX_VAR(opline->result.var));
2817728181
}
@@ -39120,6 +39124,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA
3912039124
} else {
3912139125
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
3912239126
assign_dim_op_ret_null:
39127+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
3912339128
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
3912439129
ZVAL_NULL(EX_VAR(opline->result.var));
3912539130
}
@@ -42619,6 +42624,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H
4261942624
} else {
4262042625
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
4262142626
assign_dim_op_ret_null:
42627+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
4262242628
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
4262342629
ZVAL_NULL(EX_VAR(opline->result.var));
4262442630
}
@@ -45599,6 +45605,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H
4559945605
} else {
4560045606
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
4560145607
assign_dim_op_ret_null:
45608+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
4560245609
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
4560345610
ZVAL_NULL(EX_VAR(opline->result.var));
4560445611
}
@@ -47701,6 +47708,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL
4770147708
} else {
4770247709
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
4770347710
assign_dim_op_ret_null:
47711+
FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var);
4770447712
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
4770547713
ZVAL_NULL(EX_VAR(opline->result.var));
4770647714
}

0 commit comments

Comments
 (0)