From 4170d41a66d913b672e7f76d528aea2fe15d21de Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Jan 2022 15:37:36 +0300 Subject: [PATCH] JIT: Fix incorrect FETCH_THIS elimination Fizex oss-fuzz #43159 --- ext/opcache/jit/zend_jit_trace.c | 18 ++++++++++++++++-- ext/opcache/tests/jit/assign_obj_op_001.phpt | 19 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_obj_op_001.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9a310d3e351..d885fe84cb3 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3147,8 +3147,9 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse } } -static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ssa_opcodes, int var) +static zend_bool zend_jit_may_delay_fetch_this(const zend_op_array *op_array, zend_ssa *ssa, const zend_op **ssa_opcodes, const zend_ssa_op *ssa_op) { + int var = ssa_op->result_def; int i; int use = ssa->vars[var].use_chain; const zend_op *opline; @@ -3189,6 +3190,19 @@ static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ss return 0; } + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { + if (opline->op1_type == IS_CV + && (opline+1)->op1_type == IS_CV + && (opline+1)->op1.var == opline->op1.var) { + /* skip $a->prop += $a; */ + return 0; + } + if (!zend_jit_supported_binary_op( + opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) { + return 0; + } + } + for (i = ssa->vars[var].definition; i < use; i++) { if (ssa_opcodes[i]->opcode == ZEND_DO_UCALL || ssa_opcodes[i]->opcode == ZEND_DO_FCALL_BY_NAME @@ -5610,7 +5624,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par case ZEND_FETCH_THIS: delayed_fetch_this = 0; if (ssa_op->result_def >= 0 && opline->result_type != IS_CV) { - if (zend_jit_may_delay_fetch_this(ssa, ssa_opcodes, ssa_op->result_def)) { + if (zend_jit_may_delay_fetch_this(op_array, ssa, ssa_opcodes, ssa_op)) { ssa->var_info[ssa_op->result_def].delayed_fetch_this = 1; delayed_fetch_this = 1; } diff --git a/ext/opcache/tests/jit/assign_obj_op_001.phpt b/ext/opcache/tests/jit/assign_obj_op_001.phpt new file mode 100644 index 00000000000..65ed5f7844a --- /dev/null +++ b/ext/opcache/tests/jit/assign_obj_op_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_OBJ_OP: Unsupported types +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +y.=[];})->call($test); +?> +--EXPECTF-- +Warning: Undefined property: Test::$y in %sassign_obj_op_001.php on line 6 + +Warning: Array to string conversion in %sassign_obj_op_001.php on line 6