Skip to content

Commit 6cbc911

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Fix memory leak
2 parents 339bd57 + a8bd342 commit 6cbc911

File tree

3 files changed

+60
-17
lines changed

3 files changed

+60
-17
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

+17-8
Original file line numberDiff line numberDiff line change
@@ -5574,7 +5574,8 @@ static int zend_jit_simple_assign(dasm_State **Dst,
55745574
uint32_t val_info,
55755575
zend_jit_addr res_addr,
55765576
int in_cold,
5577-
int save_r1)
5577+
int save_r1,
5578+
bool check_exception)
55785579
/* Labels: 1,2,3 */
55795580
{
55805581
zend_reg tmp_reg;
@@ -5624,7 +5625,9 @@ static int zend_jit_simple_assign(dasm_State **Dst,
56245625
ZEND_ASSERT(Z_MODE(val_addr) == IS_MEM_ZVAL && Z_REG(val_addr) == ZREG_FP);
56255626
| LOAD_32BIT_VAL FCARG1w, Z_OFFSET(val_addr)
56265627
| EXT_CALL zend_jit_undefined_op_helper, REG0
5627-
| cbz RETVALx, ->exception_handler_undef
5628+
if (check_exception) {
5629+
| cbz RETVALx, ->exception_handler_undef
5630+
}
56285631
if (save_r1) {
56295632
| ldr FCARG1x, T1 // restore
56305633
}
@@ -5933,15 +5936,15 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59335936
if (!keep_gc) {
59345937
| str Rx(tmp_reg), T1 // save
59355938
}
5936-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0)) {
5939+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0, 0)) {
59375940
return 0;
59385941
}
59395942
if (!keep_gc) {
59405943
| ldr FCARG1x, T1 // restore
59415944
}
59425945
} else {
59435946
| GET_ZVAL_PTR FCARG1x, var_use_addr, TMP1
5944-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1)) {
5947+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1, 0)) {
59455948
return 0;
59465949
}
59475950
}
@@ -5953,7 +5956,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59535956
}
59545957
| ZVAL_DTOR_FUNC var_info, opline, TMP1
59555958
if (in_cold || (RC_MAY_BE_N(var_info) && (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0)) {
5956-
if (check_exception) {
5959+
if (check_exception && !(val_info & MAY_BE_UNDEF)) {
59575960
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
59585961
| cbz REG0, >8
59595962
| b ->exception_handler
@@ -5969,6 +5972,12 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59695972
| b >8
59705973
}
59715974
}
5975+
if (check_exception && (val_info & MAY_BE_UNDEF)) {
5976+
|8:
5977+
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
5978+
| cbz REG0, >8
5979+
| b ->exception_handler
5980+
}
59725981
if (in_cold) {
59735982
|.code
59745983
} else {
@@ -5997,7 +6006,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
59976006
}
59986007
}
59996008

6000-
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0)) {
6009+
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0, check_exception)) {
60016010
return 0;
60026011
}
60036012

@@ -6097,7 +6106,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
60976106
| b >9
60986107
|.code
60996108

6100-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0)) {
6109+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0, 0)) {
61016110
return 0;
61026111
}
61036112
} else {
@@ -8351,7 +8360,7 @@ static int zend_jit_qm_assign(dasm_State **Dst, const zend_op *opline, uint32_t
83518360
}
83528361
}
83538362

8354-
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0)) {
8363+
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0, 1)) {
83558364
return 0;
83568365
}
83578366
if (!zend_jit_store_var_if_necessary(Dst, opline->result.var, res_addr, res_info)) {

ext/opcache/jit/zend_jit_x86.dasc

+18-9
Original file line numberDiff line numberDiff line change
@@ -6110,7 +6110,8 @@ static int zend_jit_simple_assign(dasm_State **Dst,
61106110
uint32_t val_info,
61116111
zend_jit_addr res_addr,
61126112
int in_cold,
6113-
int save_r1)
6113+
int save_r1,
6114+
bool check_exception)
61146115
/* Labels: 1,2,3 */
61156116
{
61166117
zend_reg tmp_reg;
@@ -6160,8 +6161,10 @@ static int zend_jit_simple_assign(dasm_State **Dst,
61606161
ZEND_ASSERT(Z_MODE(val_addr) == IS_MEM_ZVAL && Z_REG(val_addr) == ZREG_FP);
61616162
| mov FCARG1d, Z_OFFSET(val_addr)
61626163
| EXT_CALL zend_jit_undefined_op_helper, r0
6163-
| test r0, r0
6164-
| jz ->exception_handler_undef
6164+
if (check_exception) {
6165+
| test r0, r0
6166+
| jz ->exception_handler_undef
6167+
}
61656168
if (save_r1) {
61666169
| mov FCARG1a, aword T1 // restore
61676170
}
@@ -6476,15 +6479,15 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
64766479
if (!keep_gc) {
64776480
| mov aword T1, Ra(tmp_reg) // save
64786481
}
6479-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0)) {
6482+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 0, 0)) {
64806483
return 0;
64816484
}
64826485
if (!keep_gc) {
64836486
| mov FCARG1a, aword T1 // restore
64846487
}
64856488
} else {
64866489
| GET_ZVAL_PTR FCARG1a, var_use_addr
6487-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1)) {
6490+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, in_cold, 1, 0)) {
64886491
return 0;
64896492
}
64906493
}
@@ -6496,7 +6499,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
64966499
}
64976500
| ZVAL_DTOR_FUNC var_info, opline
64986501
if (in_cold || (RC_MAY_BE_N(var_info) && (var_info & (MAY_BE_ARRAY|MAY_BE_OBJECT)) != 0)) {
6499-
if (check_exception) {
6502+
if (check_exception && !(val_info & MAY_BE_UNDEF)) {
65006503
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
65016504
| je >8
65026505
| jmp ->exception_handler
@@ -6512,6 +6515,12 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
65126515
| jmp >8
65136516
}
65146517
}
6518+
if (check_exception && (val_info & MAY_BE_UNDEF)) {
6519+
|8:
6520+
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
6521+
| je >8
6522+
| jmp ->exception_handler
6523+
}
65156524
if (in_cold) {
65166525
|.code
65176526
} else {
@@ -6540,7 +6549,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
65406549
}
65416550
}
65426551

6543-
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0)) {
6552+
if (!done && !zend_jit_simple_assign(Dst, opline, var_addr, var_info, var_def_info, val_type, val_addr, val_info, res_addr, 0, 0, check_exception)) {
65446553
return 0;
65456554
}
65466555

@@ -6638,7 +6647,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
66386647
| jmp >9
66396648
|.code
66406649

6641-
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0)) {
6650+
if (!zend_jit_simple_assign(Dst, opline, var_addr, var_info, -1, (opline+1)->op1_type, op3_addr, val_info, res_addr, 0, 0, 0)) {
66426651
return 0;
66436652
}
66446653
} else {
@@ -8961,7 +8970,7 @@ static int zend_jit_qm_assign(dasm_State **Dst, const zend_op *opline, uint32_t
89618970
}
89628971
}
89638972

8964-
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0)) {
8973+
if (!zend_jit_simple_assign(Dst, opline, res_addr, res_use_info, res_info, opline->op1_type, op1_addr, op1_info, 0, 0, 0, 1)) {
89658974
return 0;
89668975
}
89678976
if (!zend_jit_store_var_if_necessary(Dst, opline->result.var, res_addr, res_info)) {

ext/opcache/tests/jit/assign_055.phpt

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
JIT ASSIGN: memory leak
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
set_error_handler(function() {
12+
(y);
13+
});
14+
$ret = new stdClass;
15+
try {
16+
$ret = $y;
17+
} catch (y) {
18+
}
19+
?>
20+
--EXPECTF--
21+
Fatal error: Uncaught Error: Undefined constant "y" in %sassign_055.php:3
22+
Stack trace:
23+
#0 %sassign_055.php(7): {closure}(2, 'Undefined varia...', '%s', 7)
24+
#1 {main}
25+
thrown in %sassign_055.php on line 3

0 commit comments

Comments
 (0)