From ce269178a94412fbaa32390ec3e0e56d5cf60481 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Oct 2023 22:50:25 +0300 Subject: [PATCH] Fixed code generation for DETCH_DIM_R Fixes oss-fuzz #63613 and #63619 --- Zend/Optimizer/zend_inference.c | 2 ++ ext/opcache/jit/zend_jit_ir.c | 37 ++++++++++++---------- ext/opcache/tests/jit/fetch_dim_r_015.phpt | 15 +++++++++ ext/opcache/tests/jit/fetch_dim_r_016.phpt | 15 +++++++++ 4 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_015.phpt create mode 100644 ext/opcache/tests/jit/fetch_dim_r_016.phpt diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 960e82e842f..b901055ef7f 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -1876,6 +1876,8 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv) } ZEND_HASH_FOREACH_END(); if (HT_IS_PACKED(ht)) { tmp &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH); + } else { + tmp &= ~MAY_BE_ARRAY_PACKED; } return tmp; } diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index b4f8f723c2a..09fb277a54d 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -11399,9 +11399,6 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, packed_loaded = 1; } else { bad_packed_key = 1; - if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) { - jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr)); - } } h = ir_CONST_LONG(val); } else { @@ -11511,9 +11508,18 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, ir_refs_add(found_inputs, ir_END()); ir_refs_add(found_vals, ref); ir_IF_FALSE(if_def); + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) { + jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr)); + } else if (type == BP_VAR_IS && not_found_exit_addr) { + jit_SIDE_EXIT(jit, ir_CONST_ADDR(not_found_exit_addr)); + } else if (type == BP_VAR_IS && result_type_guard) { + ir_END_list(*not_found_inputs); + } else { + ir_END_list(idx_not_found_inputs); + } } else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) { /* perform IS_UNDEF check only after result type guard (during deoptimization) */ - if (!result_type_guard || (op1_info & MAY_BE_ARRAY_NUMERIC_HASH)) { + if (!result_type_guard) { ir_GUARD(type_ref, ir_CONST_ADDR(exit_addr)); } } else if (type == BP_VAR_IS && not_found_exit_addr) { @@ -11530,18 +11536,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, ir_IF_TRUE(if_def); } } - if (!(op1_info & MAY_BE_ARRAY_KEY_LONG) || (packed_loaded && (op1_info & MAY_BE_ARRAY_NUMERIC_HASH))) { - if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) { - jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr)); - } else if (type == BP_VAR_IS && not_found_exit_addr) { - jit_SIDE_EXIT(jit, ir_CONST_ADDR(not_found_exit_addr)); - } else if (type == BP_VAR_IS && result_type_guard) { - ir_END_list(*not_found_inputs); - } else { - ir_END_list(idx_not_found_inputs); - } - } - if (/*!packed_loaded ||*/ (op1_info & MAY_BE_ARRAY_NUMERIC_HASH)) { + if (op1_info & MAY_BE_ARRAY_NUMERIC_HASH) { if (if_packed) { ir_IF_FALSE(if_packed); if_packed = IR_UNUSED; @@ -11575,6 +11570,16 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, } else if (packed_loaded) { ir_refs_add(found_inputs, ir_END()); ir_refs_add(found_vals, ref); + } else { + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && type == BP_VAR_R) { + jit_SIDE_EXIT(jit, ir_CONST_ADDR(exit_addr)); + } else if (type == BP_VAR_IS && not_found_exit_addr) { + jit_SIDE_EXIT(jit, ir_CONST_ADDR(not_found_exit_addr)); + } else if (type == BP_VAR_IS && result_type_guard) { + ir_END_list(*not_found_inputs); + } else { + ir_END_list(idx_not_found_inputs); + } } if (idx_not_found_inputs) { diff --git a/ext/opcache/tests/jit/fetch_dim_r_015.phpt b/ext/opcache/tests/jit/fetch_dim_r_015.phpt new file mode 100644 index 00000000000..37371a9ee49 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_015.phpt @@ -0,0 +1,15 @@ +--TEST-- +JIT FETCH_DIM_R: 015 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + 4)[-1]; +?> +DONE +--EXPECTF-- +Warning: Undefined array key -1 in %sfetch_dim_r_015.php on line 2 +DONE diff --git a/ext/opcache/tests/jit/fetch_dim_r_016.phpt b/ext/opcache/tests/jit/fetch_dim_r_016.phpt new file mode 100644 index 00000000000..eb3e6eab36a --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_016.phpt @@ -0,0 +1,15 @@ +--TEST-- +JIT FETCH_DIM_R: 016 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined array key -1 in %sfetch_dim_r_016.php on line 2 +DONE