From 94286cd596b497fcaf66017505a638633409d15b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 2 Dec 2021 16:16:54 +0300 Subject: [PATCH 01/96] Fix yet another indirect string modification by error handler problem --- Zend/tests/str_offset_008.phpt | 18 ++++++++++++++++++ ext/opcache/jit/zend_jit_helpers.c | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 Zend/tests/str_offset_008.phpt diff --git a/Zend/tests/str_offset_008.phpt b/Zend/tests/str_offset_008.phpt new file mode 100644 index 0000000000000..e99e46e59e749 --- /dev/null +++ b/Zend/tests/str_offset_008.phpt @@ -0,0 +1,18 @@ +--TEST-- +string offset 008 indirect string modification by error handler +--FILE-- + +--EXPECT-- +Err: Undefined variable $b +Err: String offset cast occurred +string(1) "x" +int(8) diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 3d7163d370678..d287416fa748d 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -921,7 +921,15 @@ static zend_string* ZEND_FASTCALL zend_jit_fetch_dim_str_r_helper(zend_string *s zend_long offset; if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) { + if (!(GC_FLAGS(str) & IS_STR_INTERNED)) { + GC_ADDREF(str); + } offset = zend_check_string_offset(dim/*, BP_VAR_R*/); + if (!(GC_FLAGS(str) & IS_STR_INTERNED) && UNEXPECTED(GC_DELREF(str) == 0)) { + zend_string *ret = zend_jit_fetch_dim_str_offset(str, offset); + zend_string_efree(str); + return ret; + } } else { offset = Z_LVAL_P(dim); } From 628670c391c1d62c9383edbb50b95e468058b023 Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Thu, 2 Dec 2021 14:19:16 +0100 Subject: [PATCH 02/96] Prepare for 8.1.2 --- NEWS | 5 ++++- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 6 +++--- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index 17e01da2f80fa..1ea24abd81860 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.1 +?? ??? ????, PHP 8.1.2 + + +02 Dec 2021, PHP 8.1.1 - IMAP: . Fixed bug #81649 (imap_(un)delete accept sequences, not single numbers). diff --git a/Zend/zend.h b/Zend/zend.h index b4cabb7ae7601..a5de7fc883bec 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.1-dev" +#define ZEND_VERSION "4.1.2-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index e6270a7523533..754603c149f7c 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.1-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.2-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index 44f483c823bf6..a7f9fd6c283c9 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 -#define PHP_RELEASE_VERSION 1 +#define PHP_RELEASE_VERSION 2 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.1-dev" -#define PHP_VERSION_ID 80101 +#define PHP_VERSION "8.1.2-dev" +#define PHP_VERSION_ID 80102 From 2fde308fc6b3b897c451d17b22a78612cd040422 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 2 Dec 2021 22:19:48 +0300 Subject: [PATCH 03/96] JIT: Fix ASSIGN_DIM_OP with undefined variable and index and user error handler, throwing an exception Fixes oss-fuzz #39422 --- ext/opcache/jit/zend_jit_helpers.c | 3 ++ ext/opcache/tests/jit/assign_dim_op_005.phpt | 32 ++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_op_005.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index d287416fa748d..07cde980efa1e 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -690,6 +690,9 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_rw_helper(zend_array *ht, zval *di case IS_UNDEF: execute_data = EG(current_execute_data); opline = EX(opline); + if (UNEXPECTED(opline->opcode == ZEND_HANDLE_EXCEPTION)) { + opline = EG(opline_before_exception); + } if (!zend_jit_undefined_op_helper_write(ht, opline->op2.var)) { if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { if (EG(exception)) { diff --git a/ext/opcache/tests/jit/assign_dim_op_005.phpt b/ext/opcache/tests/jit/assign_dim_op_005.phpt new file mode 100644 index 0000000000000..62af633eb3122 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_op_005.phpt @@ -0,0 +1,32 @@ +--TEST-- +JIT ASSIGN_DIM_OP: Undefined variable and index with exception +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +getMessage(), "\n"; +} +try { + test2(); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECT-- +Undefined variable $undef +Undefined variable $a From 42a162e535979a2871b9f9235d76febf80c38a83 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 2 Dec 2021 22:50:55 +0300 Subject: [PATCH 04/96] Add test --- ext/opcache/tests/jit/assign_dim_op_006.phpt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ext/opcache/tests/jit/assign_dim_op_006.phpt diff --git a/ext/opcache/tests/jit/assign_dim_op_006.phpt b/ext/opcache/tests/jit/assign_dim_op_006.phpt new file mode 100644 index 0000000000000..075a6c34e95d9 --- /dev/null +++ b/ext/opcache/tests/jit/assign_dim_op_006.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ASSIGN_DIM_OP 006: Cloberring array be user error handler +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +--EXPECT-- +int(0) From c4ee66856e1450568f37cebeeb05d60d1cbfbe24 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 2 Dec 2021 23:47:36 +0300 Subject: [PATCH 05/96] Tracing JIT: Fixed Zend/tests/str_offset_008.phpt failure --- ext/opcache/jit/zend_jit_x86.dasc | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 55ba4d4990e73..3ea6b38fa4545 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -12096,26 +12096,26 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, |6: } - if ((opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) || (op2_info & MAY_BE_UNDEF)) { - | SET_EX_OPLINE opline, r0 - if (opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) { - | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1 - | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | mov FCARG1d, opline->op1.var - | EXT_CALL zend_jit_undefined_op_helper, r0 - |1: - } + if ((op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_OBJECT|may_be_string))) + && (!exit_addr || !(op1_info & (MAY_BE_ARRAY|MAY_BE_OBJECT|may_be_string)))) { + if ((opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) || (op2_info & MAY_BE_UNDEF)) { + | SET_EX_OPLINE opline, r0 + if (opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) { + | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1 + | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); + | mov FCARG1d, opline->op1.var + | EXT_CALL zend_jit_undefined_op_helper, r0 + |1: + } - if (op2_info & MAY_BE_UNDEF) { - | IF_NOT_ZVAL_TYPE op2_addr, IS_UNDEF, >1 - | mov FCARG1d, opline->op2.var - | EXT_CALL zend_jit_undefined_op_helper, r0 - |1: + if (op2_info & MAY_BE_UNDEF) { + | IF_NOT_ZVAL_TYPE op2_addr, IS_UNDEF, >1 + | mov FCARG1d, opline->op2.var + | EXT_CALL zend_jit_undefined_op_helper, r0 + |1: + } } - } - if ((op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_OBJECT|may_be_string))) - && (!exit_addr || !(op1_info & (MAY_BE_ARRAY|MAY_BE_OBJECT|may_be_string)))) { if (opline->opcode != ZEND_FETCH_DIM_IS && opline->opcode != ZEND_FETCH_LIST_R) { if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) { | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr From 59dd4fd742ddbbf6a0238e89f427a32918d1dd08 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 2 Dec 2021 19:05:34 +0100 Subject: [PATCH 06/96] Fix #81681: ReflectionEnum throwing exceptions Enums are neither instantiable nor cloneable. Closes GH-7707. --- NEWS | 2 ++ ext/reflection/php_reflection.c | 4 ++-- ext/reflection/tests/bug81681.phpt | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 ext/reflection/tests/bug81681.phpt diff --git a/NEWS b/NEWS index 1ea24abd81860..57a82de06bb4e 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.2 +- Reflection: + . Fixed bug #81681 (ReflectionEnum throwing exceptions). (cmb) 02 Dec 2021, PHP 8.1.1 diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 2134d9aa72f2f..d2d84bf0af1e6 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4751,7 +4751,7 @@ ZEND_METHOD(ReflectionClass, isInstantiable) RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) { + if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) { RETURN_FALSE; } @@ -4776,7 +4776,7 @@ ZEND_METHOD(ReflectionClass, isCloneable) RETURN_THROWS(); } GET_REFLECTION_OBJECT_PTR(ce); - if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS)) { + if (ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS | ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_ENUM)) { RETURN_FALSE; } if (!Z_ISUNDEF(intern->obj)) { diff --git a/ext/reflection/tests/bug81681.phpt b/ext/reflection/tests/bug81681.phpt new file mode 100644 index 0000000000000..6b1c2278163e6 --- /dev/null +++ b/ext/reflection/tests/bug81681.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #81681 (ReflectionEnum throwing exceptions) +--FILE-- +isInstantiable()); +var_dump($reflectionEnum->isCloneable()); +?> +--EXPECT-- +bool(false) +bool(false) From 2515e788bc970af5afbecbfd90eb4211acada6d3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Dec 2021 11:13:50 +0300 Subject: [PATCH 07/96] JIT: Fix register clobbering Fixes oss-fuzz #41621 --- ext/opcache/jit/zend_jit_x86.dasc | 13 ++++++++++--- ext/opcache/tests/jit/mod_005.phpt | 26 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/mod_005.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 3ea6b38fa4545..5f4e914a6cea2 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -5000,9 +5000,6 @@ static int zend_jit_long_math_helper(dasm_State **Dst, if (opcode == ZEND_MOD) { result_reg = ZREG_RAX; - if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { - | mov aword T1, r0 // save - } } else if (Z_MODE(res_addr) == IS_REG) { if ((opline->opcode == ZEND_SL || opline->opcode == ZEND_SR) && opline->op2_type != IS_CONST) { @@ -5127,6 +5124,11 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | GET_ZVAL_LVAL result_reg, op1_addr | LONG_MATH ZEND_BW_AND, result_reg, tmp_addr } else { + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { + | mov aword T1, r0 // save + } else if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RCX) { + | mov aword T1, Ra(ZREG_RCX) // save + } result_reg = ZREG_RDX; if (op2_lval == -1) { | xor Ra(result_reg), Ra(result_reg) @@ -5142,6 +5144,8 @@ static int zend_jit_long_math_helper(dasm_State **Dst, } if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { | mov r0, aword T1 // restore + } else if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RCX) { + | mov Ra(ZREG_RCX), aword T1 // restore } } } else { @@ -5183,6 +5187,9 @@ static int zend_jit_long_math_helper(dasm_State **Dst, |.code } + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { + | mov aword T1, r0 // save + } result_reg = ZREG_RDX; | GET_ZVAL_LVAL ZREG_RAX, op1_addr |.if X64 diff --git a/ext/opcache/tests/jit/mod_005.phpt b/ext/opcache/tests/jit/mod_005.phpt new file mode 100644 index 0000000000000..8c90f6b6ef17f --- /dev/null +++ b/ext/opcache/tests/jit/mod_005.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT MOD: 005 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- +prop %= 3; + return $test; +} + +var_dump(test2(new Test)); +?> +--EXPECT-- +object(Test)#1 (1) { + ["prop"]=> + int(2) +} From 1d054b3fa7fc701afd1d21a36510ecff56489dbc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Dec 2021 13:35:28 +0300 Subject: [PATCH 08/96] Fix array object clobbering by user error handler Fixes oss-fuss #41605 and #41610 --- Zend/zend_execute.c | 10 +- Zend/zend_vm_def.h | 40 +- Zend/zend_vm_execute.h | 932 +++++++++++++++++++++++++---- ext/opcache/jit/zend_jit_helpers.c | 97 ++- 4 files changed, 938 insertions(+), 141 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index db04a2d22d4cf..d9f7789847c99 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2318,9 +2318,15 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * ZVAL_UNDEF(result); } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - } - if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + ZVAL_NULL(result); + return; + } + } else if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, type, result); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c13fc7baa7344..80db78b36adfc 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1203,8 +1203,16 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + ZEND_VM_C_GOTO(assign_dim_op_ret_null); + } + } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -2575,12 +2583,32 @@ ZEND_VM_C_LABEL(try_assign_dim_array): } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - value = GET_OP_DATA_ZVAL_PTR_DEREF(BP_VAR_R); - - if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + ZEND_VM_C_GOTO(assign_dim_error); + } + } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = GET_OP_DATA_ZVAL_PTR_UNDEF(BP_VAR_R); + if (OP_DATA_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + ZEND_VM_C_GOTO(assign_dim_error); + } + } else if (OP_DATA_TYPE & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); FREE_OP_DATA(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9aea2d2b4998f..d74e40a0427b8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22289,7 +22289,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -23236,11 +23244,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -23348,11 +23376,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -23461,11 +23509,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -23574,11 +23642,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -24796,7 +24884,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -25748,11 +25844,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -25860,11 +25976,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -25973,11 +26109,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -26086,11 +26242,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -26977,7 +27153,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = NULL; - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -27116,11 +27300,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -27228,11 +27432,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -27341,11 +27565,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -27454,11 +27698,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -28695,8 +28959,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -29642,12 +29914,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -29754,12 +30046,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -29867,12 +30179,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -29980,12 +30312,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -39284,7 +39636,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -40494,11 +40854,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -40606,11 +40986,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -40719,11 +41119,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -40832,11 +41252,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -42871,7 +43311,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -44080,11 +44528,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -44192,11 +44660,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -44305,11 +44793,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -44418,11 +44926,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -45629,7 +46157,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { dim = NULL; - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -45894,11 +46430,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -46006,11 +46562,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -46119,11 +46695,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -46232,11 +46828,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { dim = NULL; - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -47883,8 +48499,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_op_ret_null; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); @@ -49088,12 +49712,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { @@ -49200,12 +49844,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -49313,12 +49977,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var_deref((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -49426,12 +50110,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_deref_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + goto assign_dim_error; + } + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 07cde980efa1e..794b20bf8fab8 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1290,9 +1290,23 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval zval *retval; if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - retval = Z_OBJ_HT_P(object_ptr)->read_dimension(Z_OBJ_P(object_ptr), dim, type, result); + zend_object *obj = Z_OBJ_P(object_ptr); + + if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { + const zend_op *opline = EG(current_execute_data)->opline; + GC_ADDREF(obj); + zend_jit_undefined_op_helper(opline->op2.var); + dim = &EG(uninitialized_zval); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + ZVAL_NULL(result); + return; + } + } + + retval = obj->handlers->read_dimension(obj, dim, type, result); if (UNEXPECTED(retval == &EG(uninitialized_zval))) { - zend_class_entry *ce = Z_OBJCE_P(object_ptr); + zend_class_entry *ce = obj->ce; ZVAL_NULL(result); zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); @@ -1303,7 +1317,7 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval retval = result; } if (Z_TYPE_P(retval) != IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(object_ptr); + zend_class_entry *ce = obj->ce; zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); } } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) { @@ -1356,7 +1370,49 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_rw_helper(zval *object_ptr, zva static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim, zval *value, zval *result) { - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(dim != NULL)) { + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { + const zend_op *opline = EG(current_execute_data)->opline; + GC_ADDREF(obj); + zend_jit_undefined_op_helper(opline->op2.var); + dim = &EG(uninitialized_zval); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + if (result) { + ZVAL_NULL(result); + } + return; + } + } + + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + const zend_op *op_data = EG(current_execute_data)->opline + 1; + ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV); + GC_ADDREF(obj); + zend_jit_undefined_op_helper(op_data->op1.var); + value = &EG(uninitialized_zval); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + if (result) { + ZVAL_NULL(result); + } + return; + } + } else { + ZVAL_DEREF(value); + } + + Z_OBJ_HT_P(object_ptr)->write_dimension(obj, dim, value); + if (result) { + if (EXPECTED(!EG(exception))) { + ZVAL_COPY(result, value); + } else { + ZVAL_UNDEF(result); + } + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(dim != NULL)) { zend_assign_to_string_offset(object_ptr, dim, value, result); return; } @@ -1374,17 +1430,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim value = &EG(uninitialized_zval); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - ZVAL_DEREF(value); - Z_OBJ_HT_P(object_ptr)->write_dimension(Z_OBJ_P(object_ptr), dim, value); - if (result) { - if (EXPECTED(!EG(exception))) { - ZVAL_COPY(result, value); - } else { - ZVAL_UNDEF(result); - } - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { zend_throw_error(NULL, "[] operator not supported for strings"); if (result) { ZVAL_UNDEF(result); @@ -1400,16 +1446,29 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *dim, zval *value, binary_op_type binary_op) { if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zval *object = container; - zval *property = dim; + zend_object *obj = Z_OBJ_P(container); zval *z; zval rv, res; - z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv); + if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { + const zend_op *opline = EG(current_execute_data)->opline; + GC_ADDREF(obj); + zend_jit_undefined_op_helper(opline->op2.var); + dim = &EG(uninitialized_zval); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); +//??? if (retval) { +//??? ZVAL_NULL(retval); +//??? } + return; + } + } + + z = obj->handlers->read_dimension(obj, dim, BP_VAR_R, &rv); if (z != NULL) { if (binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value) == SUCCESS) { - Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res); + obj->handlers->write_dimension(obj, dim, &res); } if (z == &rv) { zval_ptr_dtor(&rv); From 4a5c05a49d140430be2b3b9741aa085170f42f6d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Dec 2021 13:40:01 +0300 Subject: [PATCH 09/96] ws --- ext/opcache/jit/zend_jit_helpers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 794b20bf8fab8..fdd4b81fdad8c 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1463,7 +1463,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d return; } } - + z = obj->handlers->read_dimension(obj, dim, BP_VAR_R, &rv); if (z != NULL) { From 8d7d87cdc40de0c3983832946571089c9d02ab8f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Dec 2021 13:40:17 +0300 Subject: [PATCH 10/96] Add test --- Zend/tests/objects_034.phpt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 Zend/tests/objects_034.phpt diff --git a/Zend/tests/objects_034.phpt b/Zend/tests/objects_034.phpt new file mode 100644 index 0000000000000..ddb11a13fea28 --- /dev/null +++ b/Zend/tests/objects_034.phpt @@ -0,0 +1,27 @@ +--TEST-- +Array object clobbering by user error handler +--FILE-- + +--EXPECT-- +NULL +NULL +NULL From c9901aa594e8ef43c0ec663dfb46c47eb7abdaee Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Dec 2021 13:52:10 +0300 Subject: [PATCH 11/96] Add missing "return" --- ext/opcache/jit/zend_jit_helpers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index fdd4b81fdad8c..31d48709fc93f 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1412,6 +1412,7 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim ZVAL_UNDEF(result); } } + return; } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(dim != NULL)) { zend_assign_to_string_offset(object_ptr, dim, value, result); return; From 929d847152ce6cdfd20d753ce8fdd47c97916c94 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 3 Dec 2021 18:43:59 +0100 Subject: [PATCH 12/96] Fix #81693: mb_check_encoding(7bit) segfaults `php_mb_check_encoding()` now uses conversion to `mbfl_encoding_wchar`. Since `mbfl_encoding_7bit` has no `input_filter`, no filter can be found. Since we don't actually need to convert to wchar, we encode to 8bit. Closes GH-7712. --- NEWS | 3 +++ ext/mbstring/libmbfl/mbfl/mbfl_convert.c | 3 ++- ext/mbstring/tests/bug81693.phpt | 10 ++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/bug81693.phpt diff --git a/NEWS b/NEWS index 57a82de06bb4e..0acf556366133 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.2 +- MBString: + . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) + - Reflection: . Fixed bug #81681 (ReflectionEnum throwing exceptions). (cmb) diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c index dda978a71223b..f6e860a35aead 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c @@ -307,7 +307,8 @@ const struct mbfl_convert_vtbl* mbfl_convert_filter_get_vtbl(const mbfl_encoding from = &mbfl_encoding_8bit; } else if (from->no_encoding == mbfl_no_encoding_base64 || from->no_encoding == mbfl_no_encoding_qprint || - from->no_encoding == mbfl_no_encoding_uuencode) { + from->no_encoding == mbfl_no_encoding_uuencode || + from->no_encoding == mbfl_no_encoding_7bit) { to = &mbfl_encoding_8bit; } diff --git a/ext/mbstring/tests/bug81693.phpt b/ext/mbstring/tests/bug81693.phpt new file mode 100644 index 0000000000000..ae52453f8765d --- /dev/null +++ b/ext/mbstring/tests/bug81693.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #81693 (mb_check_encoding(7bit) segfaults) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +bool(true) From 307e476e86e19135976ba7e686558de68dbb9b29 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Sat, 4 Dec 2021 18:04:24 +0300 Subject: [PATCH 13/96] Fixed bug #81216 (Nullsafe operator leaks dynamic property name) Fixes oss-fuzz #38542 --- NEWS | 3 +++ Zend/tests/bug81216.phpt | 10 ++++++++++ Zend/zend_compile.c | 23 ++++++++++++++--------- 3 files changed, 27 insertions(+), 9 deletions(-) create mode 100644 Zend/tests/bug81216.phpt diff --git a/NEWS b/NEWS index 0acf556366133..64d41569809ec 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.1.2 +- Core: + . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) + - MBString: . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) diff --git a/Zend/tests/bug81216.phpt b/Zend/tests/bug81216.phpt new file mode 100644 index 0000000000000..0ec08d5aeca84 --- /dev/null +++ b/Zend/tests/bug81216.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #81216: Nullsafe operator leaks dynamic property name +--FILE-- +{$str . "bar"}; +?> +DONE +--EXPECT-- +DONE diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a36a986402944..63fb6314c1a7d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2258,11 +2258,9 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */ ZEND_ASSERT(count >= offset); for (i = offset; i < count; ++i) { - opline = get_next_op(); - memcpy(opline, &oplines[i], sizeof(zend_op)); - if (opline->opcode == ZEND_JMP_NULL) { - uint32_t opnum = get_next_op_number() - 1; - zend_stack_push(&CG(short_circuiting_opnums), &opnum); + if (oplines[i].opcode != ZEND_NOP) { + opline = get_next_op(); + memcpy(opline, &oplines[i], sizeof(zend_op)); } } @@ -2890,11 +2888,18 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t opline = zend_delayed_compile_var(&obj_node, obj_ast, type, 0); zend_separate_if_call_and_write(&obj_node, obj_ast, type); if (nullsafe) { - /* We will push to the short_circuiting_opnums stack in zend_delayed_compile_end(). */ - opline = zend_delayed_emit_op(NULL, ZEND_JMP_NULL, &obj_node, NULL); - if (opline->op1_type == IS_CONST) { - Z_TRY_ADDREF_P(CT_CONSTANT(opline->op1)); + /* Flush delayed oplines */ + zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack)); + uint32_t i, count = zend_stack_count(&CG(delayed_oplines_stack)); + + for (i = 0; i < count; ++i) { + if (oplines[i].opcode != ZEND_NOP) { + opline = get_next_op(); + memcpy(opline, &oplines[i], sizeof(zend_op)); + oplines[i].opcode = ZEND_NOP; + } } + zend_emit_jmp_null(&obj_node); } } From 582a291c98afcd671f8f6318af1a79a0341848e0 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 5 Dec 2021 13:51:50 +0100 Subject: [PATCH 14/96] Use php/php-sdk-binary-tools.git for AppVeyor builds --- appveyor/build.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor/build.bat b/appveyor/build.bat index c8005734e16eb..736667e9f1db4 100644 --- a/appveyor/build.bat +++ b/appveyor/build.bat @@ -1,6 +1,6 @@ @echo off -set SDK_REMOTE=https://github.com/Microsoft/php-sdk-binary-tools.git +set SDK_REMOTE=https://github.com/php/php-sdk-binary-tools.git set SDK_BRANCH=%PHP_BUILD_SDK_BRANCH% set SDK_RUNNER=%PHP_BUILD_CACHE_SDK_DIR%\phpsdk-%PHP_BUILD_CRT%-%PLATFORM%.bat From dab6226cbe247fe926e43a1230ead15b8309be4c Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 4 Dec 2021 22:35:57 +0100 Subject: [PATCH 15/96] Fix invalid opcode for ??= on $GLOBALS Closes #81684 Closes GH-7717 --- NEWS | 2 ++ Zend/tests/bug81684.phpt | 11 +++++++++++ Zend/zend_compile.c | 4 +++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/bug81684.phpt diff --git a/NEWS b/NEWS index 64d41569809ec..f1ef2bd35efe8 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) + . Fixed bug #81684 (Using null coalesce assignment with $GLOBALS["x"] produces + opcode error). (ilutov) - MBString: . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) diff --git a/Zend/tests/bug81684.phpt b/Zend/tests/bug81684.phpt new file mode 100644 index 0000000000000..e47056187a765 --- /dev/null +++ b/Zend/tests/bug81684.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #81684: ??= on $GLOBALS produces an invalid opcode +--FILE-- + +--EXPECT-- +string(1) "x" +Done. diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 63fb6314c1a7d..c136d226e3c2d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -8986,7 +8986,9 @@ static void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */ /* Reproduce some of the zend_compile_assign() opcode fixup logic here. */ opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; - switch (var_ast->kind) { + /* Treat $GLOBALS['x'] assignment like assignment to variable. */ + zend_ast_kind kind = is_global_var_fetch(var_ast) ? ZEND_AST_VAR : var_ast->kind; + switch (kind) { case ZEND_AST_VAR: zend_emit_op_tmp(&assign_node, ZEND_ASSIGN, &var_node_w, &default_node); break; From 15e7e570a52795a6fea4af8d02f04567320d802f Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 3 Dec 2021 21:06:15 +0000 Subject: [PATCH 16/96] Fix #81658: MYSQL_OPT_LOAD_DATA_LOCAL_DIR not available in MariaDB This also introduces the boolean userland constant `MYSQLI_IS_MARIADB`. --- NEWS | 5 +++++ ext/mysqli/mysqli.c | 8 +++++++- ext/mysqli/mysqli_api.c | 2 +- ext/mysqli/mysqli_nonapi.c | 2 +- ext/mysqli/tests/mysqli_constants.phpt | 3 ++- ext/pdo_mysql/mysql_driver.c | 4 ++-- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index f1ef2bd35efe8..b172fe1160674 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,11 @@ PHP NEWS - MBString: . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) +- MySQLi: + . Fixed bug #81658 (MYSQL_OPT_LOAD_DATA_LOCAL_DIR not available in MariaDB). + (devnexen) + . Introduced MYSQLI_IS_MARIADB. (devnexen) + - Reflection: . Fixed bug #81681 (ReflectionEnum throwing exceptions). (cmb) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index f6694668ad768..b2c89aac0f3ae 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -596,7 +596,7 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_LONG_CONSTANT("MYSQLI_READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_CONNECT_TIMEOUT", MYSQL_OPT_CONNECT_TIMEOUT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, CONST_CS | CONST_PERSISTENT); -#if MYSQL_VERSION_ID >= 80021 || defined(MYSQLI_USE_MYSQLND) +#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND) REGISTER_LONG_CONSTANT("MYSQLI_OPT_LOAD_DATA_LOCAL_DIR", MYSQL_OPT_LOAD_DATA_LOCAL_DIR, CONST_CS | CONST_PERSISTENT); #endif REGISTER_LONG_CONSTANT("MYSQLI_INIT_COMMAND", MYSQL_INIT_COMMAND, CONST_CS | CONST_PERSISTENT); @@ -772,6 +772,12 @@ PHP_MINIT_FUNCTION(mysqli) REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_RELEASE", TRANS_COR_RELEASE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_NO_RELEASE", TRANS_COR_NO_RELEASE, CONST_CS | CONST_PERSISTENT); +#ifdef MARIADB_BASE_VERSION + REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", 1, CONST_CS | CONST_PERSISTENT); +#else + REGISTER_BOOL_CONSTANT("MYSQLI_IS_MARIADB", 0, CONST_CS | CONST_PERSISTENT); +#endif + #ifdef MYSQLI_USE_MYSQLND mysqlnd_reverse_api_register_api(&mysqli_reverse_api); diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 96dee255b2b96..afd86bbe93a40 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1720,7 +1720,7 @@ static int mysqli_options_get_option_zval_type(int option) #if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND) case MYSQL_SERVER_PUBLIC_KEY: #endif -#if MYSQL_VERSION_ID >= 80021 || defined(MYSQLI_USE_MYSQLND) +#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND) case MYSQL_OPT_LOAD_DATA_LOCAL_DIR: #endif return IS_STRING; diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index b905426eeae7e..3fe4408e29dd8 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -333,7 +333,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, bool is_real_connect, b unsigned int allow_local_infile = MyG(allow_local_infile); mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&allow_local_infile); -#if MYSQL_VERSION_ID >= 80021 || defined(MYSQLI_USE_MYSQLND) +#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(MYSQLI_USE_MYSQLND) if (MyG(local_infile_directory) && !php_check_open_basedir(MyG(local_infile_directory))) { mysql_options(mysql->mysql, MYSQL_OPT_LOAD_DATA_LOCAL_DIR, MyG(local_infile_directory)); } diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt index 4415f3250cc6d..0380792e06284 100644 --- a/ext/mysqli/tests/mysqli_constants.phpt +++ b/ext/mysqli/tests/mysqli_constants.phpt @@ -47,6 +47,7 @@ $expected_constants = array( "MYSQLI_GROUP_FLAG" => true, "MYSQLI_SERVER_QUERY_NO_GOOD_INDEX_USED"=> true, "MYSQLI_SERVER_QUERY_NO_INDEX_USED" => true, + "MYSQLI_IS_MARIADB" => true, "MYSQLI_TYPE_DECIMAL" => true, "MYSQLI_TYPE_TINY" => true, @@ -180,7 +181,7 @@ if ($IS_MYSQLND) { $expected_constants["MYSQLI_TYPE_JSON"] = true; } -if ($version > 80021 || $IS_MYSQLND) { +if (($version > 80021 && $constants['mysqli']['MYSQLI_IS_MARIADB']) || $IS_MYSQLND) { $expected_constants['MYSQLI_OPT_LOAD_DATA_LOCAL_DIR'] = true; } diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 09083ccfc3057..c814324af9705 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -544,7 +544,7 @@ static int pdo_mysql_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *return_ ZVAL_BOOL(return_value, H->local_infile); break; -#if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND) +#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(PDO_USE_MYSQLND) case PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY: { const char* local_infile_directory = NULL; @@ -765,7 +765,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options) #endif } -#if MYSQL_VERSION_ID >= 80021 || defined(PDO_USE_MYSQLND) +#if (MYSQL_VERSION_ID >= 80021 && !defined(MARIADB_BASE_VERSION)) || defined(PDO_USE_MYSQLND) zend_string *local_infile_directory = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_LOCAL_INFILE_DIRECTORY, NULL); if (local_infile_directory && !php_check_open_basedir(ZSTR_VAL(local_infile_directory))) { if (mysql_options(H->server, MYSQL_OPT_LOAD_DATA_LOCAL_DIR, (const char *)ZSTR_VAL(local_infile_directory))) { From 26e424465c4d6848d19bcf041c6110ff155df840 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 9 Nov 2021 12:03:59 +0100 Subject: [PATCH 17/96] Fix bug #81598: Use C.UTF-8 as LC_CTYPE locale by default Unfortunately, libedit is locale based and does not accept UTF-8 input when the C locale is used. This patch switches the default locale to C.UTF-8 instead (if it is available). This makes libedit work and I believe it shouldn't affect behavior of single-byte locale-dependent functions that PHP otherwise uses. Closes GH-7635. --- NEWS | 4 ++++ Zend/tests/lc_ctype_inheritance.phpt | 4 ++-- Zend/zend_operators.c | 9 +++++++++ Zend/zend_operators.h | 2 ++ ext/snmp/snmp.c | 2 +- ext/standard/basic_functions.c | 1 + main/main.c | 1 + 7 files changed, 20 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index b172fe1160674..9cefea074e2d7 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ PHP NEWS (devnexen) . Introduced MYSQLI_IS_MARIADB. (devnexen) +- Readline: + . Fixed bug #81598 (Cannot input unicode characters in PHP 8 interactive + shell). (Nikita) + - Reflection: . Fixed bug #81681 (ReflectionEnum throwing exceptions). (cmb) diff --git a/Zend/tests/lc_ctype_inheritance.phpt b/Zend/tests/lc_ctype_inheritance.phpt index 8971ff1969723..8c968f0615e6e 100644 --- a/Zend/tests/lc_ctype_inheritance.phpt +++ b/Zend/tests/lc_ctype_inheritance.phpt @@ -16,8 +16,8 @@ var_dump(setlocale(LC_CTYPE, "de_DE", "de-DE") !== false); var_dump(bin2hex(strtoupper("\xe4"))); var_dump(preg_match('/\w/', "\xe4")); ?> ---EXPECT-- -string(1) "C" +--EXPECTF-- +string(%d) "C%r(\.UTF-8)?%r" string(2) "e4" int(0) bool(true) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 0a516f691901a..d178b9b506fe8 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2662,6 +2662,15 @@ ZEND_API void zend_update_current_locale(void) /* {{{ */ } /* }}} */ +ZEND_API void zend_reset_lc_ctype_locale(void) +{ + /* Use the C.UTF-8 locale so that readline can process UTF-8 input, while not interfering + * with single-byte locale-dependent functions used by PHP. */ + if (!setlocale(LC_CTYPE, "C.UTF-8")) { + setlocale(LC_CTYPE, "C"); + } +} + static zend_always_inline void zend_str_tolower_impl(char *dest, const char *str, size_t length) /* {{{ */ { unsigned char *p = (unsigned char*)str; unsigned char *q = (unsigned char*)dest; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 5610d34dedb3b..2044b20b2be6e 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -472,6 +472,8 @@ ZEND_API zend_long ZEND_FASTCALL zend_atol(const char *str, size_t str_len); ZEND_API void zend_update_current_locale(void); +ZEND_API void zend_reset_lc_ctype_locale(void); + /* The offset in bytes between the value and type fields of a zval */ #define ZVAL_OFFSETOF_TYPE \ (offsetof(zval, u1.type_info) - offsetof(zval, value)) diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index f0917501751f5..a6ef3b92454d3 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -1999,7 +1999,7 @@ PHP_MINIT_FUNCTION(snmp) init_snmp("snmpapp"); /* net-snmp corrupts the CTYPE locale during initialization. */ - setlocale(LC_CTYPE, "C"); + zend_reset_lc_ctype_locale(); #ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE /* Prevent update of the snmpapp.conf file */ diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 73d92fd447f19..23f736d200905 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -528,6 +528,7 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */ * to the value in startup environment */ if (BG(locale_changed)) { setlocale(LC_ALL, "C"); + zend_reset_lc_ctype_locale(); zend_update_current_locale(); if (BG(ctype_string)) { zend_string_release_ex(BG(ctype_string), 0); diff --git a/main/main.c b/main/main.c index 7de295fe84fb3..a0f1a658c661a 100644 --- a/main/main.c +++ b/main/main.c @@ -2087,6 +2087,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zuf.getenv_function = sapi_getenv; zuf.resolve_path_function = php_resolve_path_for_zend; zend_startup(&zuf); + zend_reset_lc_ctype_locale(); zend_update_current_locale(); zend_observer_startup(); From 1f38c003d2415e97a8ba073d9d31ad42876bc001 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 25 Nov 2021 07:43:14 +0100 Subject: [PATCH 18/96] fix #81656: GCC-11 silently ignores -R Closes GH-7688. --- NEWS | 2 ++ build/php.m4 | 28 ++++++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/NEWS b/NEWS index 502dadd166dd1..49a6c06732253 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.15 +- Core: + . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) 16 Dec 2021, PHP 8.0.14 diff --git a/build/php.m4 b/build/php.m4 index 7fb9e3125d135..32b9a7417d9f4 100644 --- a/build/php.m4 +++ b/build/php.m4 @@ -275,25 +275,25 @@ dnl dnl Checks for -R, etc. switch. dnl AC_DEFUN([PHP_RUNPATH_SWITCH],[ -AC_MSG_CHECKING([if compiler supports -R]) -AC_CACHE_VAL(php_cv_cc_dashr,[ +AC_MSG_CHECKING([if compiler supports -Wl,-rpath,]) +AC_CACHE_VAL(php_cv_cc_rpath,[ SAVE_LIBS=$LIBS - LIBS="-R /usr/$PHP_LIBDIR $LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],[php_cv_cc_dashr=yes],[php_cv_cc_dashr=no]) + LIBS="-Wl,-rpath,/usr/$PHP_LIBDIR $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],[php_cv_cc_rpath=yes],[php_cv_cc_rpath=no]) LIBS=$SAVE_LIBS]) -AC_MSG_RESULT([$php_cv_cc_dashr]) -if test $php_cv_cc_dashr = "yes"; then - ld_runpath_switch=-R +AC_MSG_RESULT([$php_cv_cc_rpath]) +if test $php_cv_cc_rpath = "yes"; then + ld_runpath_switch=-Wl,-rpath, else - AC_MSG_CHECKING([if compiler supports -Wl,-rpath,]) - AC_CACHE_VAL(php_cv_cc_rpath,[ + AC_MSG_CHECKING([if compiler supports -R]) + AC_CACHE_VAL(php_cv_cc_dashr,[ SAVE_LIBS=$LIBS - LIBS="-Wl,-rpath,/usr/$PHP_LIBDIR $LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],[php_cv_cc_rpath=yes],[php_cv_cc_rpath=no]) + LIBS="-R /usr/$PHP_LIBDIR $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])],[php_cv_cc_dashr=yes],[php_cv_cc_dashr=no]) LIBS=$SAVE_LIBS]) - AC_MSG_RESULT([$php_cv_cc_rpath]) - if test $php_cv_cc_rpath = "yes"; then - ld_runpath_switch=-Wl,-rpath, + AC_MSG_RESULT([$php_cv_cc_dashr]) + if test $php_cv_cc_dashr = "yes"; then + ld_runpath_switch=-R else dnl Something innocuous. ld_runpath_switch=-L From b991ce9c1e19b912b4ca5a9b2ebc20bd5448ecd5 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sun, 5 Dec 2021 20:26:37 +0100 Subject: [PATCH 19/96] Improve final/abstract methods in interfaces error messages Closes #81683 Closes GH-7722 --- NEWS | 2 ++ Zend/tests/bug71871.phpt | 2 +- Zend/tests/bug71871_2.phpt | 2 +- Zend/zend_compile.c | 10 +++++++++- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index f1b6abbc3d9d5..472250212c8fc 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS . Fixed bug #81684 (Using null coalesce assignment with $GLOBALS["x"] produces opcode error). (ilutov) . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) + . Fixed bug #81683 (Misleading "access type ... must be public" error message + on final or abstract interface methods). (ilutov) - MBString: . Fixed bug #81693 (mb_check_encoding(7bit) segfaults). (cmb) diff --git a/Zend/tests/bug71871.phpt b/Zend/tests/bug71871.phpt index 981e7519c7652..9d93f5dd9a6f1 100644 --- a/Zend/tests/bug71871.phpt +++ b/Zend/tests/bug71871.phpt @@ -9,4 +9,4 @@ interface test { ?> --EXPECTF-- -Fatal error: Access type for interface method test::test() must be public in %s on line %d +Fatal error: Interface method test::test() must not be final in %s on line %d diff --git a/Zend/tests/bug71871_2.phpt b/Zend/tests/bug71871_2.phpt index 2781a8d495503..d1ed08f0b6cfb 100644 --- a/Zend/tests/bug71871_2.phpt +++ b/Zend/tests/bug71871_2.phpt @@ -9,4 +9,4 @@ interface test { ?> --EXPECTF-- -Fatal error: Access type for interface method test::test() must be public in %s on line %d +Fatal error: Interface method test::test() must not be abstract in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c136d226e3c2d..0b025939ec457 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7039,10 +7039,18 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string } if (in_interface) { - if (!(fn_flags & ZEND_ACC_PUBLIC) || (fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_ABSTRACT))) { + if (!(fn_flags & ZEND_ACC_PUBLIC)) { zend_error_noreturn(E_COMPILE_ERROR, "Access type for interface method " "%s::%s() must be public", ZSTR_VAL(ce->name), ZSTR_VAL(name)); } + if (fn_flags & ZEND_ACC_FINAL) { + zend_error_noreturn(E_COMPILE_ERROR, "Interface method " + "%s::%s() must not be final", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } + if (fn_flags & ZEND_ACC_ABSTRACT) { + zend_error_noreturn(E_COMPILE_ERROR, "Interface method " + "%s::%s() must not be abstract", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + } op_array->fn_flags |= ZEND_ACC_ABSTRACT; } From aa7280264e9b42a287cf38c68a019ca516db01dd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 6 Dec 2021 11:30:03 +0300 Subject: [PATCH 20/96] Fix refcount inferemce ($a += $a returns old array with RCN) Fixes oss-fuzz #41670 --- ext/opcache/Optimizer/zend_inference.c | 2 +- ext/opcache/tests/jit/assign_op_008.phpt | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/assign_op_008.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index f7e28643f448a..92ae858b707bc 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2570,7 +2570,7 @@ static zend_always_inline int _zend_update_type_info( ssa, opline->extended_value, t1, t2, opline->opcode == ZEND_ASSIGN_OP ? ssa_op->op1_def : -1, optimization_level); if (tmp & (MAY_BE_STRING|MAY_BE_ARRAY)) { - tmp |= MAY_BE_RC1; + tmp |= MAY_BE_RC1 | MAY_BE_RCN; } if (tmp & (MAY_BE_OBJECT|MAY_BE_RESOURCE)) { tmp |= MAY_BE_RC1 | MAY_BE_RCN; diff --git a/ext/opcache/tests/jit/assign_op_008.phpt b/ext/opcache/tests/jit/assign_op_008.phpt new file mode 100644 index 0000000000000..efd9418741fc0 --- /dev/null +++ b/ext/opcache/tests/jit/assign_op_008.phpt @@ -0,0 +1,22 @@ +--TEST-- +JIT ASSIGN_OP: 008 Arrays merging with itself +--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 "b" in %sassign_op_008.php on line 6 +DONE From 5459ed4c2fbc25560da3808e823c0503704a8f31 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 6 Dec 2021 13:08:27 +0300 Subject: [PATCH 21/96] Fix use after free because of data clobbering by user error handler Fixes oss-fuzz #41692 --- Zend/tests/falsetoarray_002.phpt | 15 + Zend/zend_execute.c | 19 +- Zend/zend_vm_def.h | 31 +- Zend/zend_vm_execute.h | 656 +++++++++++++++++++++-------- ext/opcache/jit/zend_jit_helpers.c | 36 +- 5 files changed, 561 insertions(+), 196 deletions(-) create mode 100644 Zend/tests/falsetoarray_002.phpt diff --git a/Zend/tests/falsetoarray_002.phpt b/Zend/tests/falsetoarray_002.phpt new file mode 100644 index 0000000000000..c01b799545965 --- /dev/null +++ b/Zend/tests/falsetoarray_002.phpt @@ -0,0 +1,15 @@ +--TEST-- +Autovivification of false to array with data clobbering by error handler +--FILE-- + +--EXPECT-- +Err: Automatic conversion of false to array is deprecated +string(0) "" diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 02eda69787a15..aa0a2e39ec438 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2508,13 +2508,24 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { - zend_false_to_array_deprecated(); - } if (type != BP_VAR_UNSET) { - array_init(container); + HashTable *ht = zend_new_array(0); + zend_uchar old_type = Z_TYPE_P(container); + + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto return_null; + } + } goto fetch_from_array; } else { + if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); + } return_null: /* for read-mode only */ if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index df0f853fba067..335c4f7a7ab71 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1217,13 +1217,23 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + ZEND_VM_C_GOTO(assign_dim_op_ret_null); + } } - ZVAL_ARR(container, zend_new_array(8)); ZEND_VM_C_GOTO(assign_dim_op_new_array); } else { dim = GET_OP2_ZVAL_PTR(BP_VAR_R); @@ -2626,10 +2636,6 @@ ZEND_VM_C_LABEL(try_assign_dim_array): FREE_OP_DATA(); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -2637,7 +2643,18 @@ ZEND_VM_C_LABEL(try_assign_dim_array): FREE_OP_DATA(); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + ZEND_VM_C_GOTO(assign_dim_error); + } + } ZEND_VM_C_GOTO(try_assign_dim_array); } } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 89f0cab5e20a1..2596d5261a41a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22459,13 +22459,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = RT_CONSTANT(opline, opline->op2); @@ -23431,10 +23441,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -23442,7 +23448,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -23568,10 +23585,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -23579,7 +23592,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -23705,10 +23729,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -23716,7 +23736,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -23841,10 +23872,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -23852,7 +23879,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -25100,13 +25138,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); @@ -26077,10 +26125,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -26088,7 +26132,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -26214,10 +26269,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -26225,7 +26276,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -26351,10 +26413,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -26362,7 +26420,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -26487,10 +26556,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -26498,7 +26563,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -27379,13 +27455,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = NULL; @@ -27555,10 +27641,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -27566,7 +27648,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -27692,10 +27785,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -27703,7 +27792,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -27829,10 +27929,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -27840,7 +27936,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -27965,10 +28072,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -27976,7 +28079,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -29206,13 +29320,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); @@ -30178,10 +30302,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -30189,7 +30309,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -30315,10 +30446,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -30326,7 +30453,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -30452,10 +30590,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -30463,7 +30597,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -30588,10 +30733,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -30599,7 +30740,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -39900,13 +40052,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = RT_CONSTANT(opline, opline->op2); @@ -41135,10 +41297,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -41146,7 +41304,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -41272,10 +41441,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -41283,7 +41448,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -41409,10 +41585,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -41420,7 +41592,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -41545,10 +41728,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -41556,7 +41735,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -43620,13 +43810,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); @@ -44854,10 +45054,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -44865,7 +45061,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -44991,10 +45198,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -45002,7 +45205,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -45128,10 +45342,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -45139,7 +45349,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -45264,10 +45485,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -45275,7 +45492,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -46475,13 +46703,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = NULL; @@ -46779,10 +47017,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -46790,7 +47024,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -46916,10 +47161,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -46927,7 +47168,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -47053,10 +47305,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -47064,7 +47312,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -47189,10 +47448,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -47200,7 +47455,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -48833,13 +49099,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL } zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + HashTable *ht; + zend_uchar old_type; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - if (Z_TYPE_P(container) == IS_FALSE) { + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } } - ZVAL_ARR(container, zend_new_array(8)); goto assign_dim_op_new_array; } else { dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); @@ -50063,10 +50339,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -50074,7 +50346,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -50200,10 +50483,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -50211,7 +50490,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -50337,10 +50627,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -50348,7 +50634,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { @@ -50473,10 +50770,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); - } - if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { @@ -50484,7 +50777,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ UNDEF_RESULT(); } else { - ZVAL_ARR(object_ptr, zend_new_array(8)); + HashTable *ht = zend_new_array(8); + zend_uchar old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } goto try_assign_dim_array; } } else { diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 2779636831420..2aeb68cbf8305 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -1152,9 +1152,15 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval } ZVAL_UNDEF(result); } else if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); zend_array *arr = zend_new_array(0); ZVAL_ARR(object_ptr, arr); + GC_ADDREF(arr); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(arr) == 0)) { + zend_array_destroy(arr); + ZVAL_NULL(result); + return; + } zval *var; if (dim) { if (type == BP_VAR_W) { @@ -1247,12 +1253,6 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim return; } - if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { - const zend_op *opline = EG(current_execute_data)->opline; - zend_jit_undefined_op_helper(opline->op2.var); - dim = &EG(uninitialized_zval); - } - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { const zend_op *op_data = EG(current_execute_data)->opline + 1; ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV); @@ -1266,9 +1266,17 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim ZVAL_UNDEF(result); } } else if (Z_TYPE_P(object_ptr) == IS_FALSE) { - zend_false_to_array_deprecated(); zend_array *arr = zend_new_array(0); ZVAL_ARR(object_ptr, arr); + GC_ADDREF(arr); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(arr) == 0)) { + zend_array_destroy(arr); + if (result) { + ZVAL_NULL(result); + } + return; + } zval *var = dim ? zend_jit_fetch_dim_w_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); @@ -1284,6 +1292,11 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim ZVAL_COPY(result, var); } } else { + if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { + const zend_op *opline = EG(current_execute_data)->opline; + zend_jit_undefined_op_helper(opline->op2.var); + dim = &EG(uninitialized_zval); + } zend_throw_error(NULL, "Cannot use a scalar value as an array"); if (result) { ZVAL_UNDEF(result); @@ -1335,9 +1348,14 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zend_wrong_string_offset_error(); } } else if (Z_TYPE_P(container) == IS_FALSE) { - zend_false_to_array_deprecated(); zend_array *arr = zend_new_array(0); ZVAL_ARR(container, arr); + GC_ADDREF(arr); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(arr) == 0)) { + zend_array_destroy(arr); + return; + } zval *var = dim ? zend_jit_fetch_dim_rw_helper(arr, dim) : zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval)); From c29f6baaee5e4d1bc826a7c1414f912b21c3e8f8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 6 Dec 2021 14:22:07 +0300 Subject: [PATCH 22/96] JIT: Fix incorrect elimination of type store Fixes oss-fuzz #41995 --- ext/opcache/jit/zend_jit.c | 12 +++++++++--- ext/opcache/tests/jit/mul_008.phpt | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/mul_008.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index c4d2fdc4ce2a1..48d3d55d32e0a 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2341,7 +2341,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if (opline->result_type != IS_UNUSED) { res_use_info = -1; - if (opline->result_type == IS_CV) { + if (opline->result_type == IS_CV + && ssa_op->result_use >= 0 + && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); if (Z_MODE(res_use_addr) != IS_REG @@ -2403,7 +2405,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } else { res_use_info = -1; - if (opline->result_type == IS_CV) { + if (opline->result_type == IS_CV + && ssa_op->result_use >= 0 + && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); if (Z_MODE(res_use_addr) != IS_REG @@ -2458,7 +2462,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } else { res_use_info = -1; - if (opline->result_type == IS_CV) { + if (opline->result_type == IS_CV + && ssa_op->result_use >= 0 + && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); if (Z_MODE(res_use_addr) != IS_REG diff --git a/ext/opcache/tests/jit/mul_008.phpt b/ext/opcache/tests/jit/mul_008.phpt new file mode 100644 index 0000000000000..d890a86c8f485 --- /dev/null +++ b/ext/opcache/tests/jit/mul_008.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT MUL: 008 incorrect elimination of type store +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %smul_008.php:6 +Stack trace: +#0 %smul_008.php(8): foo(%d) +#1 {main} + thrown in %smul_008.php on line 6 From 7b629afe4e9411c8fb5a68a2641d33027a9784e6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 6 Dec 2021 15:59:30 +0300 Subject: [PATCH 23/96] Fixed incorrect DCE of a constructor call Fixez oss-fuzz #42049 --- ext/opcache/Optimizer/dce.c | 5 ++++- ext/opcache/tests/opt/dce_012.phpt | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/dce_012.phpt diff --git a/ext/opcache/Optimizer/dce.c b/ext/opcache/Optimizer/dce.c index f0f67055dfa7e..47f5f271062e2 100644 --- a/ext/opcache/Optimizer/dce.c +++ b/ext/opcache/Optimizer/dce.c @@ -592,7 +592,10 @@ int dce_optimize_op_array(zend_op_array *op_array, zend_ssa *ssa, zend_bool reor while ((i = zend_bitset_pop_first(ctx.instr_worklist, ctx.instr_worklist_len)) >= 0) { zend_bitset_excl(ctx.instr_dead, i); add_operands_to_worklists(&ctx, &op_array->opcodes[i], &ssa->ops[i], ssa, 1); - if (i < op_array->last && op_array->opcodes[i+1].opcode == ZEND_OP_DATA) { + if (i < op_array->last + && (op_array->opcodes[i+1].opcode == ZEND_OP_DATA + || (op_array->opcodes[i].opcode == ZEND_NEW + && op_array->opcodes[i+1].opcode == ZEND_DO_FCALL))) { zend_bitset_excl(ctx.instr_dead, i+1); add_operands_to_worklists(&ctx, &op_array->opcodes[i+1], &ssa->ops[i+1], ssa, 1); } diff --git a/ext/opcache/tests/opt/dce_012.phpt b/ext/opcache/tests/opt/dce_012.phpt new file mode 100644 index 0000000000000..49cde14b33c33 --- /dev/null +++ b/ext/opcache/tests/opt/dce_012.phpt @@ -0,0 +1,26 @@ +--TEST-- +Incorrect DCE of constructor DO_FCALL +--FILE-- +orop1 = 'abc'; + } + + foreach (range(0, 6) as $levels) { + print "$levels level" . ($levels == C ? "" : "s") . "aaa"; + } + + $obj->prop1 = null; +} +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "C" in %sdce_012.php:11 +Stack trace: +#0 %sdce_012.php(16): test() +#1 {main} + thrown in %sdce_012.php on line 11 From daf79e2d91dc4dd47f516229ebc5922ad35f27ab Mon Sep 17 00:00:00 2001 From: Aliaksandr Bystry Date: Tue, 30 Nov 2021 14:23:50 +0100 Subject: [PATCH 24/96] Fix #75917: SplFileObject::seek broken with CSV flags Closes GH-7697. --- NEWS | 4 ++++ ext/spl/spl_directory.c | 2 ++ ext/spl/tests/bug75917.phpt | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 ext/spl/tests/bug75917.phpt diff --git a/NEWS b/NEWS index 49a6c06732253..767b2978d4fb2 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,10 @@ PHP NEWS - Core: . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) +- Spl: + . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr + Bystry) + 16 Dec 2021, PHP 8.0.14 - Core: diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index c7dd8b472173f..045aad5bc1b02 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1939,6 +1939,8 @@ static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_obje /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */ if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + spl_filesystem_file_free_line(intern); + if (php_stream_eof(intern->u.file.stream)) { if (!silent) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Cannot read from file %s", intern->file_name); diff --git a/ext/spl/tests/bug75917.phpt b/ext/spl/tests/bug75917.phpt new file mode 100644 index 0000000000000..c9bc02869c2d1 --- /dev/null +++ b/ext/spl/tests/bug75917.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #75917 (SplFileObject::seek broken with CSV flags) +--FILE-- +fputcsv($row); +} +$tmp->setFlags(0); +$tmp->seek(23); +var_dump($tmp->current()); + +$tmp->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY); +$tmp->seek(23); +var_dump($tmp->current()); +?> +--EXPECT-- +bool(false) +bool(false) From cf377eefa66d76a83cf71dca9166015ccb97bb27 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 6 Dec 2021 21:56:04 +0100 Subject: [PATCH 25/96] Don't convert assign op operand types in opcache This is the same change as 56b18d478ed9e40afd66860e82017d5c2017eac1 but for ASSIGN_OP. Changing the operand type may change the error message and can result in different behavior with operator overloading. As with the other patch, if there is strong interest this could be added to the DFA pass instead, with an appropriate type check. --- Zend/Optimizer/pass1.c | 30 ++------------- Zend/tests/assign_op_type_error.phpt | 57 ++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 Zend/tests/assign_op_type_error.phpt diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 110babf3e95d4..695348a389179 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -104,33 +104,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) break; case ZEND_ASSIGN_OP: - if (opline->op2_type == IS_CONST) { - if (opline->extended_value == ZEND_ADD - || opline->extended_value == ZEND_SUB - || opline->extended_value == ZEND_MUL - || opline->extended_value == ZEND_DIV - || opline->extended_value == ZEND_POW) { - if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { - /* don't optimize if it should produce a runtime numeric string error */ - if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) { - convert_scalar_to_number(&ZEND_OP2_LITERAL(opline)); - } - } - } else if (opline->extended_value == ZEND_MOD - || opline->extended_value == ZEND_SL - || opline->extended_value == ZEND_SR) { - zval *op2 = &ZEND_OP2_LITERAL(opline); - if (Z_TYPE_P(op2) != IS_LONG) { - if (!zend_is_op_long_compatible(op2)) { - break; - } - convert_to_long(op2); - } - } else if (opline->extended_value == ZEND_CONCAT) { - if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) { - convert_to_string(&ZEND_OP2_LITERAL(opline)); - } - } + if (opline->extended_value == ZEND_CONCAT && opline->op2_type == IS_CONST + && Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) { + convert_to_string(&ZEND_OP2_LITERAL(opline)); } break; diff --git a/Zend/tests/assign_op_type_error.phpt b/Zend/tests/assign_op_type_error.phpt new file mode 100644 index 0000000000000..5f175613e20b8 --- /dev/null +++ b/Zend/tests/assign_op_type_error.phpt @@ -0,0 +1,57 @@ +--TEST-- +TypeError for compound assignment operations +--FILE-- +getMessage(), "\n"; +} +try { + $x -= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x *= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x /= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x **= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x %= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x <<= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + $x >>= "1"; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Unsupported operand types: array + string +Unsupported operand types: array - string +Unsupported operand types: array * string +Unsupported operand types: array / string +Unsupported operand types: array ** string +Unsupported operand types: array % string +Unsupported operand types: array << string +Unsupported operand types: array >> string From 08f1d470fb6cc418264884dc291e7d9b428bde5e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 7 Dec 2021 11:46:32 +0300 Subject: [PATCH 26/96] Separate "cold" code --- Zend/zend_execute.c | 6 +-- Zend/zend_vm_def.h | 33 +++++++++--- Zend/zend_vm_execute.h | 117 +++++++++++++++++++---------------------- 3 files changed, 81 insertions(+), 75 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index aa0a2e39ec438..084eb34a1b016 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1425,17 +1425,17 @@ static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPL return zend_binary_ops[opcode - ZEND_ADD](ret, op1, op2); } -static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zval *property OPLINE_DC EXECUTE_DATA_DC) { zval *value; zval *z; zval rv, res; value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if ((z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv)) != NULL) { + if ((z = obj->handlers->read_dimension(obj, property, BP_VAR_R, &rv)) != NULL) { if (zend_binary_op(&res, z, value OPLINE_CC) == SUCCESS) { - Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res); + obj->handlers->write_dimension(obj, property, &res); } if (z == &rv) { zval_ptr_dtor(&rv); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 335c4f7a7ab71..5632931cf2150 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1145,6 +1145,27 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP) ZEND_VM_NEXT_OPCODE_EX(1, 2); } +ZEND_VM_COLD_HELPER(zend_assign_dim_op_obj_undef_helper, ANY, ANY, zend_object *obj) +{ + USE_OPLINE + zval *dim; + + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + FREE_OP_DATA(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } + FREE_OP2(); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP) { USE_OPLINE @@ -1203,19 +1224,15 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZEND_VM_C_GOTO(assign_dim_op_ret_null); - } + ZEND_VM_DISPATCH_TO_HELPER(zend_assign_dim_op_obj_undef_helper, obj, obj); } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2596d5261a41a..96e21e38241d3 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -799,6 +799,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HAN ZEND_VM_NEXT_OPCODE_EX(1, 2); } +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_assign_dim_op_obj_undef_helper_SPEC(zend_object *obj ZEND_OPCODE_HANDLER_ARGS_DC) +{ + USE_OPLINE + zval *dim; + + GC_ADDREF(obj); + dim = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -22445,19 +22466,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -25124,19 +25141,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -27441,19 +27454,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -29306,19 +29315,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -40038,19 +40043,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -43796,19 +43797,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -46689,19 +46686,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; @@ -49085,19 +49078,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); - dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } + ZEND_VM_TAIL_CALL(zend_assign_dim_op_obj_undef_helper_SPEC(obj ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC)); } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { HashTable *ht; zend_uchar old_type; From efb901ebedf941039241c6194c452f8a16d807aa Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 7 Dec 2021 18:26:18 +0100 Subject: [PATCH 27/96] Skip bug_36798.phpt for PDO_DBLIB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason, this test fails now with "Incorrect syntax near ''. [SELECT '�' as test FROM test WHERE id = '1']", so we skip it. --- ext/pdo/tests/bug_36798.phpt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/pdo/tests/bug_36798.phpt b/ext/pdo/tests/bug_36798.phpt index 1ce192acc9286..3deeaa9a198dd 100644 --- a/ext/pdo/tests/bug_36798.phpt +++ b/ext/pdo/tests/bug_36798.phpt @@ -10,7 +10,8 @@ PDOTest::skip(); if (!strncasecmp(getenv('PDOTEST_DSN'), 'oci', strlen('oci'))){ if (!strpos(strtolower(getenv('PDOTEST_DSN')), 'charset=we8mswin1252')) die('skip expected output valid for Oracle with WE8MSWIN1252 character set'); - +} elseif (!strncasecmp(getenv('PDOTEST_DSN'), 'dblib', strlen('dblib'))) { + die('skip not for pdo_dblib'); } ?> From 7e080183f48b8da54038ecaedd1534cd49cf56b0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 9 Dec 2021 18:15:47 +0300 Subject: [PATCH 28/96] Fix crush after compilation of nullsafe operator introduced in 307e476e86e19135976ba7e686558de68dbb9b29 Now we flush only delayed opcodes realted to this nullsafe operator. Fixes oss-fuzz #42152 --- Zend/tests/bug81216_2.phpt | 15 +++++++++++++++ Zend/zend_compile.c | 35 +++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 Zend/tests/bug81216_2.phpt diff --git a/Zend/tests/bug81216_2.phpt b/Zend/tests/bug81216_2.phpt new file mode 100644 index 0000000000000..8bf347a80e57c --- /dev/null +++ b/Zend/tests/bug81216_2.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #81216_2: Nullsafe operator leaks dynamic property name +--FILE-- +x; +var_dump($a); +?> +--EXPECT-- +array(2) { + [0]=> + NULL + [1]=> + NULL +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0b025939ec457..7a338775174e0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2258,9 +2258,11 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */ ZEND_ASSERT(count >= offset); for (i = offset; i < count; ++i) { - if (oplines[i].opcode != ZEND_NOP) { + if (EXPECTED(oplines[i].opcode != ZEND_NOP)) { opline = get_next_op(); memcpy(opline, &oplines[i], sizeof(zend_op)); + } else { + opline = CG(active_op_array)->opcodes + oplines[i].extended_value; } } @@ -2888,15 +2890,28 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t opline = zend_delayed_compile_var(&obj_node, obj_ast, type, 0); zend_separate_if_call_and_write(&obj_node, obj_ast, type); if (nullsafe) { - /* Flush delayed oplines */ - zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack)); - uint32_t i, count = zend_stack_count(&CG(delayed_oplines_stack)); - - for (i = 0; i < count; ++i) { - if (oplines[i].opcode != ZEND_NOP) { - opline = get_next_op(); - memcpy(opline, &oplines[i], sizeof(zend_op)); - oplines[i].opcode = ZEND_NOP; + if (obj_node.op_type == IS_TMP_VAR) { + /* Flush delayed oplines */ + zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack)); + uint32_t var = obj_node.u.op.var; + uint32_t count = zend_stack_count(&CG(delayed_oplines_stack)); + uint32_t i = count; + + while (i > 0 && oplines[i-1].result_type == IS_TMP_VAR && oplines[i-1].result.var == var) { + i--; + if (oplines[i].op1_type == IS_TMP_VAR) { + var = oplines[i].op1.var; + } else { + break; + } + } + for (; i < count; ++i) { + if (oplines[i].opcode != ZEND_NOP) { + opline = get_next_op(); + memcpy(opline, &oplines[i], sizeof(zend_op)); + oplines[i].opcode = ZEND_NOP; + oplines[i].extended_value = opline - CG(active_op_array)->opcodes; + } } } zend_emit_jmp_null(&obj_node); From 0ac3d78d7d05e254680f58d072e36b3b6779ee78 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 10 Dec 2021 01:39:28 +0300 Subject: [PATCH 29/96] Fix incorrect JMP optimization Fixes oss-fuzz #42155 --- ext/opcache/Optimizer/dfa_pass.c | 12 ++++++++---- ext/opcache/tests/opt/jmp_002.phpt | 13 +++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/opt/jmp_002.phpt diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 7a03c8ba02a56..823eccdb4f23f 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -730,9 +730,13 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) uint32_t op_num; zend_op *opline; zend_ssa_op *ssa_op; + zend_bool can_follow = 1; while (next_block_num < ssa->cfg.blocks_count && !(ssa->cfg.blocks[next_block_num].flags & ZEND_BB_REACHABLE)) { + if (ssa->cfg.blocks[next_block_num].flags & ZEND_BB_UNREACHABLE_FREE) { + can_follow = 0; + } next_block_num++; } @@ -744,7 +748,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) switch (opline->opcode) { case ZEND_JMP: optimize_jmp: - if (block->successors[0] == next_block_num) { + if (block->successors[0] == next_block_num && can_follow) { MAKE_NOP(opline); removed_ops++; goto optimize_nop; @@ -765,7 +769,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) goto optimize_jmp; } } else { - if (block->successors[0] == next_block_num) { + if (block->successors[0] == next_block_num && can_follow) { take_successor_0(ssa, block_num, block); if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_UNDEF)) { opline->opcode = ZEND_CHECK_VAR; @@ -796,7 +800,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) goto optimize_nop; } } else if (block->successors_count == 2) { - if (block->successors[0] == next_block_num) { + if (block->successors[0] == next_block_num && can_follow) { take_successor_0(ssa, block_num, block); if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_UNDEF)) { opline->opcode = ZEND_CHECK_VAR; @@ -830,7 +834,7 @@ static int zend_dfa_optimize_jmps(zend_op_array *op_array, zend_ssa *ssa) } else if (block->successors_count == 2) { if (block->successors[0] == block->successors[1]) { take_successor_0(ssa, block_num, block); - if (block->successors[0] == next_block_num) { + if (block->successors[0] == next_block_num && can_follow) { if (opline->op1_type == IS_CV && (OP1_INFO() & MAY_BE_UNDEF)) { opline->opcode = ZEND_CHECK_VAR; opline->op2.num = 0; diff --git a/ext/opcache/tests/opt/jmp_002.phpt b/ext/opcache/tests/opt/jmp_002.phpt new file mode 100644 index 0000000000000..cd7f05b225dac --- /dev/null +++ b/ext/opcache/tests/opt/jmp_002.phpt @@ -0,0 +1,13 @@ +--TEST-- +JMP 002: JMP around unreachable FREE +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECT-- +DONE From 5675ebe649352ffa89754defd87019223b88b4e5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 9 Dec 2021 15:36:26 +0100 Subject: [PATCH 30/96] Fix #81585: cached_chunks are not counted to real_size on shutdown The amount of allocated system memory is kept in `real_size`, including the allocated `cached_chunks`. Thus, we need to keep the proper count at the end of the shutdown. Closes GH-7745. --- NEWS | 2 ++ Zend/zend_alloc.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 767b2978d4fb2..9207f3cc6d5c8 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) + . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). + (cmb) - Spl: . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 0d3e41776d732..5738c030a5822 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2303,10 +2303,10 @@ void zend_mm_shutdown(zend_mm_heap *heap, bool full, bool silent) #endif memset(heap->free_slot, 0, sizeof(heap->free_slot)); #if ZEND_MM_STAT || ZEND_MM_LIMIT - heap->real_size = ZEND_MM_CHUNK_SIZE; + heap->real_size = (heap->cached_chunks_count + 1) * ZEND_MM_CHUNK_SIZE; #endif #if ZEND_MM_STAT - heap->real_peak = ZEND_MM_CHUNK_SIZE; + heap->real_peak = (heap->cached_chunks_count + 1) * ZEND_MM_CHUNK_SIZE; #endif heap->chunks_count = 1; heap->peak_chunks_count = 1; From 6f42c073cf80f699b754274d2f163f3b6f7e4966 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 10 Dec 2021 14:32:47 +0300 Subject: [PATCH 31/96] Remove range inference for booleans. Range inference for bolleans and longs comparison was incorrect. Fizes oss-fuzz #fuzz-42161.php --- ext/opcache/Optimizer/zend_inference.c | 157 +------------------------ ext/opcache/Optimizer/zend_ssa.c | 8 -- ext/opcache/tests/jit/cmp_008.phpt | 26 ++++ 3 files changed, 28 insertions(+), 163 deletions(-) create mode 100644 ext/opcache/tests/jit/cmp_008.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index 92ae858b707bc..e4bb7ec3454a9 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -996,8 +996,6 @@ int zend_inference_calc_range(const zend_op_array *op_array, zend_ssa *ssa, int int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, zend_ssa_op* ssa_op, int var, zend_ssa_range *tmp) { - zend_long op1_min, op2_min, op1_max, op2_max; - tmp->underflow = 0; tmp->overflow = 0; switch (opline->opcode) { @@ -1025,8 +1023,8 @@ int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, tmp->min = ZEND_LONG_MIN; tmp->max = ZEND_LONG_MAX; } else { - op1_min = OP1_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); + zend_long op1_min = OP1_MIN_RANGE(); + zend_long op1_max = OP1_MAX_RANGE(); tmp->min = ~op1_max; tmp->max = ~op1_min; } @@ -1059,144 +1057,6 @@ int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, } } break; - case ZEND_BOOL: - case ZEND_JMPZ_EX: - case ZEND_JMPNZ_EX: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - tmp->min = (op1_min > 0 || op1_max < 0); - tmp->max = (op1_min != 0 || op1_max != 0); - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_BOOL_NOT: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - tmp->min = (op1_min == 0 && op1_max == 0); - tmp->max = (op1_min <= 0 && op1_max >= 0); - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_BOOL_XOR: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - op1_min = (op1_min > 0 || op1_max < 0); - op1_max = (op1_min != 0 || op1_max != 0); - op2_min = (op2_min > 0 || op2_max < 0); - op2_max = (op2_min != 0 || op2_max != 0); - tmp->min = 0; - tmp->max = 1; - if (op1_min == op1_max && op2_min == op2_max) { - if (op1_min == op2_min) { - tmp->max = 0; - } else { - tmp->min = 1; - } - } - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_IS_IDENTICAL: - case ZEND_IS_EQUAL: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - - tmp->min = (op1_min == op1_max && - op2_min == op2_max && - op1_min == op2_max); - tmp->max = (op1_min <= op2_max && op1_max >= op2_min); - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_IS_NOT_IDENTICAL: - case ZEND_IS_NOT_EQUAL: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - - tmp->min = (op1_min > op2_max || op1_max < op2_min); - tmp->max = (op1_min != op1_max || - op2_min != op2_max || - op1_min != op2_max); - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_IS_SMALLER: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - - tmp->min = op1_max < op2_min; - tmp->max = op1_min < op2_max; - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; - case ZEND_IS_SMALLER_OR_EQUAL: - if (ssa_op->result_def == var) { - if (OP1_HAS_RANGE() && OP2_HAS_RANGE()) { - op1_min = OP1_MIN_RANGE(); - op2_min = OP2_MIN_RANGE(); - op1_max = OP1_MAX_RANGE(); - op2_max = OP2_MAX_RANGE(); - - tmp->min = op1_max <= op2_min; - tmp->max = op1_min <= op2_max; - return 1; - } else { - tmp->min = 0; - tmp->max = 1; - return 1; - } - } - break; case ZEND_QM_ASSIGN: case ZEND_JMP_SET: case ZEND_COALESCE: @@ -1222,13 +1082,6 @@ int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, } } break; - case ZEND_ASSERT_CHECK: - if (ssa_op->result_def == var) { - tmp->min = 0; - tmp->max = 1; - return 1; - } - break; case ZEND_SEND_VAR: if (ssa_op->op1_def == var) { if (ssa_op->op1_def >= 0) { @@ -1409,12 +1262,6 @@ int zend_inference_propagate_range(const zend_op_array *op_array, zend_ssa *ssa, tmp->max = ZEND_LONG_MAX; tmp->overflow = 0; return 1; - } else if (mask == MAY_BE_BOOL) { - tmp->underflow = 0; - tmp->min = 0; - tmp->max = 1; - tmp->overflow = 0; - return 1; } } } diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index 23b78222839de..26d0b8b385f4c 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -335,10 +335,6 @@ static void place_essa_pis( if (Z_TYPE_P(zv) == IS_LONG) { add_val2 = Z_LVAL_P(zv); - } else if (Z_TYPE_P(zv) == IS_FALSE) { - add_val2 = 0; - } else if (Z_TYPE_P(zv) == IS_TRUE) { - add_val2 = 1; } else { var1 = -1; } @@ -356,10 +352,6 @@ static void place_essa_pis( zval *zv = CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1); if (Z_TYPE_P(zv) == IS_LONG) { add_val1 = Z_LVAL_P(CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op1)); - } else if (Z_TYPE_P(zv) == IS_FALSE) { - add_val1 = 0; - } else if (Z_TYPE_P(zv) == IS_TRUE) { - add_val1 = 1; } else { var2 = -1; } diff --git a/ext/opcache/tests/jit/cmp_008.phpt b/ext/opcache/tests/jit/cmp_008.phpt new file mode 100644 index 0000000000000..6216de5527726 --- /dev/null +++ b/ext/opcache/tests/jit/cmp_008.phpt @@ -0,0 +1,26 @@ +--TEST-- +JIT CMP: 008 Wrong range inference for comparison between IS_LONG and IS_FALSE/IS_TRUE +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $a in %scmp_008.php on line 3 + +Warning: Undefined variable $a in %scmp_008.php on line 3 + +Fatal error: Uncaught DivisionByZeroError: Modulo by zero in %scmp_008.php:3 +Stack trace: +#0 %scmp_008.php(6): test() +#1 {main} + thrown in %scmp_008.php on line 3 From 7daf01258df783f63d6b960767122001fd3885a3 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 10 Dec 2021 17:29:44 +0100 Subject: [PATCH 32/96] Fix GH-7748: gethostbyaddr outputs binary string `getnameinfo(3)` returns zero on success; all other values need to be regarded as failure. --- NEWS | 3 +++ ext/standard/dns.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index daaa3611eeec5..80f56d484fe18 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,9 @@ PHP NEWS . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr Bystry) +- Standard: + . Fixed bug GH-7748 (gethostbyaddr outputs binary string). (cmb) + 02 Dec 2021, PHP 8.1.1 - IMAP: diff --git a/ext/standard/dns.c b/ext/standard/dns.c index e88e5a79db114..6d22e644a8eff 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -182,14 +182,14 @@ static zend_string *php_gethostbyaddr(char *ip) if (inet_pton(AF_INET6, ip, &sa6.sin6_addr)) { sa6.sin6_family = AF_INET6; - if (getnameinfo((struct sockaddr *)&sa6, sizeof(sa6), out, sizeof(out), NULL, 0, NI_NAMEREQD) < 0) { + if (getnameinfo((struct sockaddr *)&sa6, sizeof(sa6), out, sizeof(out), NULL, 0, NI_NAMEREQD) != 0) { return zend_string_init(ip, strlen(ip), 0); } return zend_string_init(out, strlen(out), 0); } else if (inet_pton(AF_INET, ip, &sa4.sin_addr)) { sa4.sin_family = AF_INET; - if (getnameinfo((struct sockaddr *)&sa4, sizeof(sa4), out, sizeof(out), NULL, 0, NI_NAMEREQD) < 0) { + if (getnameinfo((struct sockaddr *)&sa4, sizeof(sa4), out, sizeof(out), NULL, 0, NI_NAMEREQD) != 0) { return zend_string_init(ip, strlen(ip), 0); } return zend_string_init(out, strlen(out), 0); From 98175fc7f1623873ceb2e9a017a319d19bfb3912 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 12 Dec 2021 13:41:37 +0100 Subject: [PATCH 33/96] Fix openssl_x509_checkpurpose_basic.phpt This test fails because san-cert.pem and san-ca.pem have expired. We fix that by using the CertificateGenerator to generate temporary certs during the test run. Since san-cert.pem and san-ca.pem have been identical, we only generate one certificate. Closes GH-7763. --- .../openssl_x509_checkpurpose_basic.phpt | 10 +++++- ext/openssl/tests/san-ca.pem | 15 --------- ext/openssl/tests/san-cert.pem | 31 ------------------- 3 files changed, 9 insertions(+), 47 deletions(-) delete mode 100644 ext/openssl/tests/san-ca.pem delete mode 100644 ext/openssl/tests/san-cert.pem diff --git a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt index 99b4f0bdff312..35629bd936266 100644 --- a/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt +++ b/ext/openssl/tests/openssl_x509_checkpurpose_basic.phpt @@ -8,10 +8,14 @@ if (OPENSSL_VERSION_NUMBER < 0x10000000) die("skip Output requires OpenSSL 1.0") ?> --FILE-- saveCaCert(__DIR__ . "/san-cert.pem"); + $cert = "file://" . __DIR__ . "/cert.crt"; $bert = "file://" . __DIR__ . "/bug41033.pem"; $sert = "file://" . __DIR__ . "/san-cert.pem"; -$cpca = __DIR__ . "/san-ca.pem"; +$cpca = __DIR__ . "/san-cert.pem"; $utfl = __DIR__ . "/sni_server_uk.pem"; $rcrt = openssl_x509_read($cert); @@ -84,6 +88,10 @@ var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_SMIME_ENCRYPT, array($cpc var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_CRL_SIGN, array($cpca), $utfl)); var_dump(openssl_x509_checkpurpose($sert, X509_PURPOSE_ANY, array($cpca), $utfl)); ?> +--CLEAN-- + --EXPECT-- bool(false) bool(false) diff --git a/ext/openssl/tests/san-ca.pem b/ext/openssl/tests/san-ca.pem deleted file mode 100644 index 88682ba2dcf65..0000000000000 --- a/ext/openssl/tests/san-ca.pem +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICYTCCAcqgAwIBAgIJAIaqxtY5dwjtMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJNTjEUMBIGA1UEBxMLTWlubmVhcG9saXMxITAfBgNV -BAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDAeFw0xMzA5MjQwODA1NTFaFw0y -MTEyMTEwODA1NTFaMFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJNTjEUMBIGA1UE -BxMLTWlubmVhcG9saXMxITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRl -ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsFGqfbU/8D+KjroQl4XMyt9m -dcSP7iZtqphOu9nVZxYAAqfaqj8FnC/pwYV3TU6ZHndLTQAllwYT3sQBQPPGmZQ9 -clSIMEL003t3pi4ZVXkttG6Vvr+Z9PBcHhlKLQ7WMHnn4qctllWXTSoyTQpkETF3 -Fc3mrG5G37BhoUno7NECAwEAAaM9MDswOQYDVR0RBDIwMIILZXhhbXBsZS5vcmeC -D3d3dy5leGFtcGxlLm9yZ4IQdGVzdC5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQUF -AAOBgQBf/FZhzheIcQJ+dyTk8xQ/nJLvpmBhbd1LNtfwk/MsC9UHsz4QXs9sBw1k -rH0FjoqgM6avj7zKHJFTj6q7Rd+OX5V4HynYPhX67sWbN3KWEHffL98nGGd/bo3X -pSjNk5vnyKYiwdUUe11Ac9csh0HcSBbhOYjy0T/i9AlQcKbuCg== ------END CERTIFICATE----- diff --git a/ext/openssl/tests/san-cert.pem b/ext/openssl/tests/san-cert.pem deleted file mode 100644 index 923d490e72fd3..0000000000000 --- a/ext/openssl/tests/san-cert.pem +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICYTCCAcqgAwIBAgIJAIaqxtY5dwjtMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV -BAYTAlVTMQswCQYDVQQIEwJNTjEUMBIGA1UEBxMLTWlubmVhcG9saXMxITAfBgNV -BAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDAeFw0xMzA5MjQwODA1NTFaFw0y -MTEyMTEwODA1NTFaMFMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJNTjEUMBIGA1UE -BxMLTWlubmVhcG9saXMxITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRl -ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsFGqfbU/8D+KjroQl4XMyt9m -dcSP7iZtqphOu9nVZxYAAqfaqj8FnC/pwYV3TU6ZHndLTQAllwYT3sQBQPPGmZQ9 -clSIMEL003t3pi4ZVXkttG6Vvr+Z9PBcHhlKLQ7WMHnn4qctllWXTSoyTQpkETF3 -Fc3mrG5G37BhoUno7NECAwEAAaM9MDswOQYDVR0RBDIwMIILZXhhbXBsZS5vcmeC -D3d3dy5leGFtcGxlLm9yZ4IQdGVzdC5leGFtcGxlLm9yZzANBgkqhkiG9w0BAQUF -AAOBgQBf/FZhzheIcQJ+dyTk8xQ/nJLvpmBhbd1LNtfwk/MsC9UHsz4QXs9sBw1k -rH0FjoqgM6avj7zKHJFTj6q7Rd+OX5V4HynYPhX67sWbN3KWEHffL98nGGd/bo3X -pSjNk5vnyKYiwdUUe11Ac9csh0HcSBbhOYjy0T/i9AlQcKbuCg== ------END CERTIFICATE----- ------BEGIN PRIVATE KEY----- -MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALBRqn21P/A/io66 -EJeFzMrfZnXEj+4mbaqYTrvZ1WcWAAKn2qo/BZwv6cGFd01OmR53S00AJZcGE97E -AUDzxpmUPXJUiDBC9NN7d6YuGVV5LbRulb6/mfTwXB4ZSi0O1jB55+KnLZZVl00q -Mk0KZBExdxXN5qxuRt+wYaFJ6OzRAgMBAAECgYB11e5iWvqjPmQEZRdnnJU0VD8u -n7ItT+Nk6qtb4gY8Abj6DWIW+01th5vqqJ8FvGyartFVYa69kuM+srG/zevAZWeu -fGZtwiwZR4DRSyRcPp4rnNiksK3dkAZA6UewmRDPv8uyHJlXc5i+Ft1ILJ5Q5jgn -UkC4z3EJP5Se9KZywQJBAOO4lRq42wLsYr2SDrQDSs4leie3FKc2bgvjF7Djosh1 -ZYbf55F5b9w1zgnccmni2HkqOnyFu4SKarmXyCsYxrkCQQDGNvnUh7/zZswrdWZ/ -PMp9zVDTh/5Oc2B4ByNLw1ERDwYhjchKgPRlQvn4cp3Pwf3UYPQ/8XGXzzEJey3A -r0rZAkBf/tDEOgcBPXsGZQrTscuYCU5sbY5ESvqrAilbhSp7DJom+D5bIfEYyIm5 -uHd20Yzlzvpmwc1huyPwZt6X5FLpAkATDReoGMAXSesXxjnqwtIHk2NQYYLM0YQV -JUJ8NrKk/Bevw+vbVVeoH+7ctU97t36JGiR/vNoZKD3jVmaIXZDJAkEA4wJbwzIo -L32mu9VmZa7wjmfkraQEmXTPaA5D9lNC0AwRTgkj+x2Qe1vawNblNK9PPLBDdplQ -L//53ADq/wv5rA== ------END PRIVATE KEY----- From 778513f60512f85dd4e10a848e0a4f4f4ef3b9d1 Mon Sep 17 00:00:00 2001 From: SATO Kentaro Date: Mon, 6 Dec 2021 06:59:52 +0900 Subject: [PATCH 34/96] Fix error message allocation of PDO PgSQL Closes GH-7723. --- NEWS | 3 +++ ext/pdo_pgsql/pgsql_driver.c | 2 +- ext/pdo_pgsql/tests/gh7723.phpt | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 ext/pdo_pgsql/tests/gh7723.phpt diff --git a/NEWS b/NEWS index 9207f3cc6d5c8..18a8b747a0b1e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ PHP NEWS . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) +- PDO_PGSQL: + . Fixed error message allocation of PDO PgSQL. (SATO Kentaro) + - Spl: . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr Bystry) diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index a5b0a22f2057b..b6449095ca0cb 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -87,7 +87,7 @@ int _pdo_pgsql_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, int errcode, const char * } if (msg) { - einfo->errmsg = estrdup(msg); + einfo->errmsg = pestrdup(msg, dbh->is_persistent); } else if (errmsg) { einfo->errmsg = _pdo_pgsql_trim_message(errmsg, dbh->is_persistent); diff --git a/ext/pdo_pgsql/tests/gh7723.phpt b/ext/pdo_pgsql/tests/gh7723.phpt new file mode 100644 index 0000000000000..bbbf5fd5bc21c --- /dev/null +++ b/ext/pdo_pgsql/tests/gh7723.phpt @@ -0,0 +1,30 @@ +--TEST-- +GitHub #7723 (Fix error message allocation of PDO PgSQL) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_PERSISTENT, true); +$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); +$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); + +$st = $db->prepare('select 1'); +for ($i = 0; ++$i <= 2;) { + try { + $st->bindValue(':invalid', $i); + } catch (PDOException $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +SQLSTATE[HY093]: Invalid parameter number: :invalid +SQLSTATE[HY093]: Invalid parameter number: :invalid From 0b3a9376701c3e8095d4fdaa2c363b26df8d20f9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 11 Dec 2021 22:16:00 +0100 Subject: [PATCH 35/96] Fix GH-7759: Incorrect return types for hash() and hash_hmac() `hash()` and `hash_hmac()` never return `false`; only `hash_file()` and `hash_hmac_file()` return `false` in case the data cannot be read. Closes GH-7760. --- NEWS | 4 ++++ ext/hash/hash.stub.php | 4 ++-- ext/hash/hash_arginfo.h | 13 +++++++++---- ext/opcache/Optimizer/zend_func_info.c | 4 ++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 18a8b747a0b1e..020add82e597e 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,10 @@ PHP NEWS . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) +- Hash: + . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). + (cmb) + - PDO_PGSQL: . Fixed error message allocation of PDO PgSQL. (SATO Kentaro) diff --git a/ext/hash/hash.stub.php b/ext/hash/hash.stub.php index c0d4cbca7c3d5..250fb68ee4e9f 100644 --- a/ext/hash/hash.stub.php +++ b/ext/hash/hash.stub.php @@ -2,11 +2,11 @@ /** @generate-function-entries */ -function hash(string $algo, string $data, bool $binary = false): string|false {} +function hash(string $algo, string $data, bool $binary = false): string {} function hash_file(string $algo, string $filename, bool $binary = false): string|false {} -function hash_hmac(string $algo, string $data, string $key, bool $binary = false): string|false {} +function hash_hmac(string $algo, string $data, string $key, bool $binary = false): string {} function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false): string|false {} diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index db043da97b477..5aef2c11d1d61 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -1,7 +1,7 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9352e0ac98e2ac53dc15d5024f9ef0c8092c4e9c */ + * Stub hash: f73c6fa1a4ac1ca93f87775bbe69fbdb2deb5746 */ -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") @@ -13,14 +13,19 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_file, 0, 2, MAY_BE_STRING|M ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_hmac, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash_hmac, 0, 3, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() -#define arginfo_hash_hmac_file arginfo_hash_hmac +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_hmac_file, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) + ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_hash_init, 0, 1, HashContext, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 3589aa1b3c2ef..84c9d20966cae 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -581,9 +581,9 @@ static const func_info_t func_infos[] = { F1("ob_gzhandler", MAY_BE_FALSE | MAY_BE_STRING), /* ext/hash */ - F1("hash", MAY_BE_FALSE | MAY_BE_STRING), + F1("hash", MAY_BE_STRING), F1("hash_file", MAY_BE_FALSE | MAY_BE_STRING), - F1("hash_hmac", MAY_BE_FALSE | MAY_BE_STRING), + F1("hash_hmac", MAY_BE_STRING), F1("hash_hmac_algos", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), F1("hash_hmac_file", MAY_BE_FALSE | MAY_BE_STRING), F1("hash_hkdf", MAY_BE_STRING), From 6d5f2ba78d85f24e69eee5c7c3948171b9fc3b05 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 12 Dec 2021 16:57:57 +0100 Subject: [PATCH 36/96] macOS 10.14 runners are no longer available via Azure Pipeline These images have already been deprecated for two months[1]. Thus, we upgrade to macOS 10.15. Since clang 12 is picky about `int-in-bool-context` warning, we disable `-Werror`. [1] --- azure/macos/job.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/azure/macos/job.yml b/azure/macos/job.yml index 4b979d41a8672..a27a16fb336cd 100644 --- a/azure/macos/job.yml +++ b/azure/macos/job.yml @@ -5,7 +5,7 @@ parameters: jobs: - job: ${{ parameters.configurationName }} pool: - vmImage: 'macOS-10.14' + vmImage: 'macOS-10.15' steps: - template: brew.yml - script: | @@ -66,7 +66,6 @@ jobs: --enable-intl \ --with-mhash \ --with-sodium \ - --enable-werror \ --with-config-file-path=/etc \ --with-config-file-scan-dir=/etc/php.d displayName: 'Configure Build' From 206c521a1f980c1c422543f3a17fca619e9ec5ee Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 12 Dec 2021 19:53:02 +0100 Subject: [PATCH 37/96] Fix GH-7757: Multi-inherited final constant causes fatal error "Diamond" inheritance of final constants is supposed to be supported. Closes GH-7767. --- NEWS | 2 ++ .../final_constants/final_const13.phpt | 18 ++++++++++++++++++ Zend/zend_inheritance.c | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/constants/final_constants/final_const13.phpt diff --git a/NEWS b/NEWS index 28575db948d25..c6ae9489f96f4 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ PHP NEWS on final or abstract interface methods). (ilutov) . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) + . Fixed bug GH-7757 (Multi-inherited final constant causes fatal error). + (cmb) - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). diff --git a/Zend/tests/constants/final_constants/final_const13.phpt b/Zend/tests/constants/final_constants/final_const13.phpt new file mode 100644 index 0000000000000..5e19e8a212695 --- /dev/null +++ b/Zend/tests/constants/final_constants/final_const13.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug GH-7757 (Multi-inherited final constant causes fatal error) +--FILE-- + +--EXPECT-- diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 4903ef4b3828b..020c5e6553920 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -1605,7 +1605,7 @@ static bool do_inherit_constant_check( } zend_class_constant *old_constant = Z_PTR_P(zv); - if ((ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_FINAL)) { + if (parent_constant->ce != old_constant->ce && (ZEND_CLASS_CONST_FLAGS(parent_constant) & ZEND_ACC_FINAL)) { zend_error_noreturn(E_COMPILE_ERROR, "%s::%s cannot override final constant %s::%s", ZSTR_VAL(old_constant->ce->name), ZSTR_VAL(name), ZSTR_VAL(parent_constant->ce->name), ZSTR_VAL(name) From c435e67746ab8d9c9e3946395f57bde6a6f51b89 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 12 Dec 2021 18:37:15 +0100 Subject: [PATCH 38/96] Fix GH-7765: php_oci_cleanup_global_handles segfaults at second call We must not use the TSRM accessor macros in GINIT and GSHUTDOWN, but rather use the passed pointers directly. For simplicity, we inline `php_oci_cleanup_global_handles()`, and also the `PHP_OCI_CALL()` macros; the latter are unlikely to be needed here, but don't hurt. Closes GH-7766. --- NEWS | 4 ++++ ext/oci8/oci8.c | 33 ++++++++++++++------------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/NEWS b/NEWS index 020add82e597e..6f1a19ddd8a76 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) +- OCI8: + . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second + call). (cmb) + - PDO_PGSQL: . Fixed error message allocation of PDO PgSQL. (SATO Kentaro) diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index ad9b23a9c40ac..a7abc6be859ac 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -239,24 +239,6 @@ static void php_oci_init_global_handles(void) } /* }}} */ -/* {{{ php_oci_cleanup_global_handles() - * - * Free global handles (if they were initialized before) - */ -static void php_oci_cleanup_global_handles(void) -{ - if (OCI_G(err)) { - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR)); - OCI_G(err) = NULL; - } - - if (OCI_G(env)) { - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV)); - OCI_G(env) = NULL; - } -} -/* }}} */ - /* {{{ PHP_GINIT_FUNCTION * * Zerofill globals during module init @@ -270,10 +252,23 @@ static PHP_GINIT_FUNCTION(oci) /* {{{ PHP_GSHUTDOWN_FUNCTION * * Called for thread shutdown in ZTS, after module shutdown for non-ZTS + * Free global handles (if they were initialized before) */ static PHP_GSHUTDOWN_FUNCTION(oci) { - php_oci_cleanup_global_handles(); + if (oci_globals->err) { + oci_globals->in_call = 1; + OCIHandleFree((dvoid *) oci_globals->err, OCI_HTYPE_ERROR); + oci_globals->in_call = 0; + oci_globals->err = NULL; + } + + if (oci_globals->env) { + oci_globals->in_call = 1; + OCIHandleFree((dvoid *) oci_globals->env, OCI_HTYPE_ENV); + oci_globals->in_call = 0; + oci_globals->env = NULL; + } } /* }}} */ From e79dbe1124bc5e556ab87ce6a4bfa3826108a2fa Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 13 Dec 2021 11:49:51 +0300 Subject: [PATCH 39/96] JIT: Fix crash during compilation of function with incompletely constructed SSA Fixes oss-fuzz #42200 --- ext/opcache/jit/zend_jit.c | 5 ++++- ext/opcache/tests/jit/mod_006.phpt | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/mod_006.phpt diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 48d3d55d32e0a..bbe879b9fddd2 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2311,7 +2311,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } end = ssa->cfg.blocks[b].start + ssa->cfg.blocks[b].len - 1; for (i = ssa->cfg.blocks[b].start; i <= end; i++) { - zend_ssa_op *ssa_op = &ssa->ops[i]; + zend_ssa_op *ssa_op = ssa->ops ? &ssa->ops[i] : NULL; opline = op_array->opcodes + i; switch (opline->opcode) { case ZEND_INIT_FCALL: @@ -2342,6 +2342,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op res_use_info = -1; if (opline->result_type == IS_CV + && ssa->vars && ssa_op->result_use >= 0 && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); @@ -2406,6 +2407,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op res_use_info = -1; if (opline->result_type == IS_CV + && ssa->vars && ssa_op->result_use >= 0 && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); @@ -2463,6 +2465,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op res_use_info = -1; if (opline->result_type == IS_CV + && ssa->vars && ssa_op->result_use >= 0 && !ssa->vars[ssa_op->result_use].no_val) { zend_jit_addr res_use_addr = RES_USE_REG_ADDR(); diff --git a/ext/opcache/tests/jit/mod_006.phpt b/ext/opcache/tests/jit/mod_006.phpt new file mode 100644 index 0000000000000..b13ef68a8e1ba --- /dev/null +++ b/ext/opcache/tests/jit/mod_006.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT MOD: 005 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file From 230de7721f17ca0aeb85d819f1d4001a6be56d22 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 13 Dec 2021 13:08:05 +0300 Subject: [PATCH 40/96] Fix incorrect optimization that leads to memory leak Fixes oss-fuzz #42221 --- ext/opcache/Optimizer/sccp.c | 4 +++- ext/opcache/tests/opt/sccp_034.phpt | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/sccp_034.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index 7792311637632..bdeb883aa562a 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -2279,7 +2279,9 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var, removed_ops = remove_call(ctx, opline, ssa_op); } else if (opline->opcode == ZEND_TYPE_CHECK && (opline->op1_type & (IS_VAR|IS_TMP_VAR)) - && !value_known(&ctx->values[ssa_op->op1_use])) { + && (!value_known(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_ARRAY(&ctx->values[ssa_op->op1_use]) + || IS_PARTIAL_OBJECT(&ctx->values[ssa_op->op1_use]))) { /* For TYPE_CHECK we may compute the result value without knowing the * operand, based on type inference information. Make sure the operand is * freed and leave further cleanup to DCE. */ diff --git a/ext/opcache/tests/opt/sccp_034.phpt b/ext/opcache/tests/opt/sccp_034.phpt new file mode 100644 index 0000000000000..8fafc89178a64 --- /dev/null +++ b/ext/opcache/tests/opt/sccp_034.phpt @@ -0,0 +1,16 @@ +--TEST-- +SCCP 034: memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $y in %ssccp_034.php on line 2 + +Warning: Undefined variable $y in %ssccp_034.php on line 2 +DONE From cbc0b1afeb97044f7a813e8678736649c15f3974 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 13 Dec 2021 14:59:30 +0300 Subject: [PATCH 41/96] Fix array clobering by user error handler Fixes oss-fuzz #42234 --- Zend/tests/objects_034.phpt | 10 +- Zend/tests/objects_035.phpt | 25 ++ Zend/zend_execute.c | 39 +- Zend/zend_vm_def.h | 20 +- Zend/zend_vm_execute.h | 640 ++++++++++------------------- ext/opcache/jit/zend_jit_helpers.c | 61 ++- 6 files changed, 317 insertions(+), 478 deletions(-) create mode 100644 Zend/tests/objects_035.phpt diff --git a/Zend/tests/objects_034.phpt b/Zend/tests/objects_034.phpt index ddb11a13fea28..e7cc5f9e90cff 100644 --- a/Zend/tests/objects_034.phpt +++ b/Zend/tests/objects_034.phpt @@ -2,7 +2,15 @@ Array object clobbering by user error handler --FILE-- +DONE +--EXPECT-- +DONE diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d9f7789847c99..a8f5c27071662 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1264,9 +1264,9 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_string_offset zend_type_error("Cannot access offset of type %s on string", zend_zval_type_name(offset)); } -static zend_never_inline void zend_assign_to_object_dim(zval *object, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_object_dim(zend_object *obj, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC) { - Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), dim, value); + obj->handlers->write_dimension(obj, dim, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), value); @@ -1300,12 +1300,14 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * zval *value; zval *z; zval rv, res; + zend_object *obj = Z_OBJ_P(object); + GC_ADDREF(obj); value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if ((z = Z_OBJ_HT_P(object)->read_dimension(Z_OBJ_P(object), property, BP_VAR_R, &rv)) != NULL) { + if ((z = obj->handlers->read_dimension(obj, property, BP_VAR_R, &rv)) != NULL) { if (zend_binary_op(&res, z, value OPLINE_CC) == SUCCESS) { - Z_OBJ_HT_P(object)->write_dimension(Z_OBJ_P(object), property, &res); + obj->handlers->write_dimension(obj, property, &res); } if (z == &rv) { zval_ptr_dtor(&rv); @@ -1321,6 +1323,9 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * } } FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *ref, zval *value OPLINE_DC EXECUTE_DATA_DC) @@ -2317,22 +2322,17 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * } ZVAL_UNDEF(result); } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZVAL_NULL(result); - return; - } } else if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, type, result); + retval = obj->handlers->read_dimension(obj, dim, type, result); if (UNEXPECTED(retval == &EG(uninitialized_zval))) { - zend_class_entry *ce = Z_OBJCE_P(container); + zend_class_entry *ce = obj->ce; ZVAL_NULL(result); zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); @@ -2343,7 +2343,7 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * retval = result; } if (Z_TYPE_P(retval) != IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(container); + zend_class_entry *ce = obj->ce; zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); } } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) { @@ -2356,6 +2356,9 @@ static zend_always_inline void zend_fetch_dimension_address(zval *result, zval * ZEND_ASSERT(EG(exception) && "read_dimension() returned NULL without exception"); ZVAL_UNDEF(result); } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else { if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { @@ -2508,13 +2511,16 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z ZVAL_CHAR(result, c); } } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); if (ZEND_CONST_COND(dim_type == IS_CV, 1) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { dim = ZVAL_UNDEFINED_OP2(); } if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, type, result); + retval = obj->handlers->read_dimension(obj, dim, type, result); ZEND_ASSERT(result != NULL); if (retval) { @@ -2526,6 +2532,9 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } else { ZVAL_NULL(result); } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else { if (type != BP_VAR_IS && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { container = ZVAL_UNDEFINED_OP1(); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 80db78b36adfc..0648ddac77055 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2583,35 +2583,29 @@ ZEND_VM_C_LABEL(try_assign_dim_array): } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZEND_VM_C_GOTO(assign_dim_error); - } } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = GET_OP_DATA_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP_DATA_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZEND_VM_C_GOTO(assign_dim_error); - } } else if (OP_DATA_TYPE & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); FREE_OP_DATA(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (OP2_TYPE == IS_UNUSED) { zend_use_new_element_for_string(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d74e40a0427b8..a5300d9099b01 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -23243,34 +23243,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -23375,35 +23369,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -23508,35 +23496,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -23641,34 +23623,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -25843,34 +25819,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -25975,35 +25945,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -26108,35 +26072,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -26241,34 +26199,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -27299,34 +27251,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -27431,35 +27377,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -27564,35 +27504,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -27697,34 +27631,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -29914,34 +29842,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -30046,35 +29968,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -30179,35 +30095,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -30312,34 +30222,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -40853,34 +40757,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -40985,35 +40883,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -41118,35 +41010,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -41251,34 +41137,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DA } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CONST == IS_UNUSED) { zend_use_new_element_for_string(); @@ -44527,34 +44407,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -44659,35 +44533,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -44792,35 +44660,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -44925,34 +44787,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { zend_use_new_element_for_string(); @@ -46429,34 +46285,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -46561,35 +46411,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -46694,35 +46538,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -46827,34 +46665,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_D } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); @@ -49712,34 +49544,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CONST & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -49844,35 +49670,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -49977,35 +49797,29 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); @@ -50110,34 +49924,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_ } } if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_error; - } } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } - zend_assign_to_object_dim(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (IS_CV == IS_UNUSED) { zend_use_new_element_for_string(); diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 31d48709fc93f..4595afdc17873 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -992,13 +992,15 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_str_is_helper(zend_string *str, zva static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval *dim, zval *result) { zval *retval; + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); dim = &EG(uninitialized_zval); } - retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, BP_VAR_R, result); + retval = obj->handlers->read_dimension(obj, dim, BP_VAR_R, result); if (retval) { if (result != retval) { @@ -1009,18 +1011,23 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval } else { ZVAL_NULL(result); } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval *dim, zval *result) { zval *retval; + zend_object *obj = Z_OBJ_P(container); + GC_ADDREF(obj); if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); dim = &EG(uninitialized_zval); } - retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, BP_VAR_IS, result); + retval = obj->handlers->read_dimension(obj, dim, BP_VAR_IS, result); if (retval) { if (result != retval) { @@ -1031,6 +1038,9 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval } else { ZVAL_NULL(result); } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void) @@ -1292,16 +1302,11 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { const zend_op *opline = EG(current_execute_data)->opline; - GC_ADDREF(obj); zend_jit_undefined_op_helper(opline->op2.var); dim = &EG(uninitialized_zval); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZVAL_NULL(result); - return; - } } retval = obj->handlers->read_dimension(obj, dim, type, result); @@ -1330,6 +1335,9 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval ZEND_ASSERT(EG(exception) && "read_dimension() returned NULL without exception"); ZVAL_UNDEF(result); } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { if (!dim) { zend_throw_error(NULL, "[] operator not supported for strings"); @@ -1373,38 +1381,23 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) { const zend_op *opline = EG(current_execute_data)->opline; - GC_ADDREF(obj); zend_jit_undefined_op_helper(opline->op2.var); dim = &EG(uninitialized_zval); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - if (result) { - ZVAL_NULL(result); - } - return; - } } if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { const zend_op *op_data = EG(current_execute_data)->opline + 1; ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV); - GC_ADDREF(obj); zend_jit_undefined_op_helper(op_data->op1.var); value = &EG(uninitialized_zval); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - if (result) { - ZVAL_NULL(result); - } - return; - } } else { ZVAL_DEREF(value); } - Z_OBJ_HT_P(object_ptr)->write_dimension(obj, dim, value); + obj->handlers->write_dimension(obj, dim, value); if (result) { if (EXPECTED(!EG(exception))) { ZVAL_COPY(result, value); @@ -1412,6 +1405,9 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim ZVAL_UNDEF(result); } } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } return; } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(dim != NULL)) { zend_assign_to_string_offset(object_ptr, dim, value, result); @@ -1451,18 +1447,11 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d zval *z; zval rv, res; + GC_ADDREF(obj); if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) { const zend_op *opline = EG(current_execute_data)->opline; - GC_ADDREF(obj); zend_jit_undefined_op_helper(opline->op2.var); dim = &EG(uninitialized_zval); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); -//??? if (retval) { -//??? ZVAL_NULL(retval); -//??? } - return; - } } z = obj->handlers->read_dimension(obj, dim, BP_VAR_R, &rv); @@ -1484,6 +1473,12 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d //??? ZVAL_NULL(retval); //??? } } + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); +//??? if (retval) { +//??? ZVAL_NULL(retval); +//??? } + } } else { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (!dim) { From fe320e83aee316de07305f7808bdb158ba8b3fea Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 13 Dec 2021 16:28:45 +0300 Subject: [PATCH 42/96] Tracing JIT: Fix reference counting Fixes oss-fuzz #42225 --- ext/opcache/jit/zend_jit_x86.dasc | 9 ++++--- ext/opcache/tests/jit/fetch_obj_008.phpt | 31 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 ext/opcache/tests/jit/fetch_obj_008.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 5f4e914a6cea2..cb41c6a2656e9 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -11865,7 +11865,7 @@ static int zend_jit_zval_copy_deref(dasm_State **Dst, zend_jit_addr res_addr, ze return 1; } -static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline) +static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline, uint32_t op1_info) { switch (opline->opcode) { case ZEND_FETCH_OBJ_FUNC_ARG: @@ -11877,7 +11877,8 @@ static zend_bool zend_jit_may_avoid_refcounting(const zend_op *opline) /* break missing intentionally */ case ZEND_FETCH_OBJ_R: case ZEND_FETCH_OBJ_IS: - if (opline->op2_type == IS_CONST + if ((op1_info & MAY_BE_OBJECT) + && opline->op2_type == IS_CONST && Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_STRING && Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] != '\0') { return 1; @@ -11956,7 +11957,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, && (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) && (ssa_op+1)->op1_use == ssa_op->result_def && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF) - (MAY_BE_STRING|MAY_BE_LONG))) - && zend_jit_may_avoid_refcounting(opline+1)) { + && zend_jit_may_avoid_refcounting(opline+1, res_info)) { result_avoid_refcounting = 1; ssa->var_info[ssa_op->result_def].avoid_refcounting = 1; } @@ -13225,7 +13226,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, && !(flags & ZEND_JIT_EXIT_FREE_OP1) && (res_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) && (ssa_op+1)->op1_use == ssa_op->result_def - && zend_jit_may_avoid_refcounting(opline+1)) { + && zend_jit_may_avoid_refcounting(opline+1, res_info)) { result_avoid_refcounting = 1; ssa->var_info[ssa_op->result_def].avoid_refcounting = 1; } diff --git a/ext/opcache/tests/jit/fetch_obj_008.phpt b/ext/opcache/tests/jit/fetch_obj_008.phpt new file mode 100644 index 0000000000000..38c5b8a539889 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_obj_008.phpt @@ -0,0 +1,31 @@ +--TEST-- +JIT: FETCH_OBJ 008 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +prop = "A $e B"; + $a->prop->prop . $a->prop = "C"; + return "test"; + } +} + +$a = new A; +$a->prop = new B; +?> +DONE +--EXPECTF-- +Warning: Undefined variable $e in %sfetch_obj_008.php on line 9 + +Warning: Attempt to read property "prop" on string in %sfetch_obj_008.php on line 10 +DONE From c787f42ceb9b2f0961f8f5accd59dfcd4a1f1342 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 13 Dec 2021 22:38:23 +0300 Subject: [PATCH 43/96] Combine ADDREF/DELREF --- Zend/zend_execute.c | 7 +-- Zend/zend_vm_def.h | 14 +++--- Zend/zend_vm_execute.h | 112 ++++++++++++++++++++--------------------- 3 files changed, 64 insertions(+), 69 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a8f5c27071662..e13092491b59f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1295,14 +1295,12 @@ static zend_always_inline int zend_binary_op(zval *ret, zval *op1, zval *op2 OPL return zend_binary_ops[opcode - ZEND_ADD](ret, op1, op2); } -static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zval *property OPLINE_DC EXECUTE_DATA_DC) { zval *value; zval *z; zval rv, res; - zend_object *obj = Z_OBJ_P(object); - GC_ADDREF(obj); value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); if ((z = obj->handlers->read_dimension(obj, property, BP_VAR_R, &rv)) != NULL) { @@ -1323,9 +1321,6 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * } } FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *ref, zval *value OPLINE_DC EXECUTE_DATA_DC) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0648ddac77055..fca5af71da717 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1203,19 +1203,19 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - ZEND_VM_C_GOTO(assign_dim_op_ret_null); - } } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a5300d9099b01..f569ff6ba8ff9 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22288,19 +22288,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -24859,19 +24859,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -27104,19 +27104,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -28887,19 +28887,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -39539,19 +39539,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -43190,19 +43190,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -46012,19 +46012,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = NULL; if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); @@ -48331,19 +48331,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - goto assign_dim_op_ret_null; - } } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); From cd8e6f5f7bf72a8056579d64227acd04926e6b09 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 14 Dec 2021 11:36:33 +0300 Subject: [PATCH 44/96] Preloading: don't remove INCLUDE_OE_EVAL nstructions with used result --- ext/opcache/ZendAccelerator.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index fe19787061ffc..6883979e7d131 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -4075,7 +4075,8 @@ static void preload_remove_empty_includes(void) if (opline->opcode == ZEND_INCLUDE_OR_EVAL && opline->extended_value != ZEND_EVAL && opline->op1_type == IS_CONST && - Z_TYPE_P(RT_CONSTANT(opline, opline->op1)) == IS_STRING) { + Z_TYPE_P(RT_CONSTANT(opline, opline->op1)) == IS_STRING && + opline->result_type == IS_UNUSED) { zend_string *resolved_path = preload_resolve_path(Z_STR_P(RT_CONSTANT(opline, opline->op1))); @@ -4121,7 +4122,7 @@ static void preload_remove_empty_includes(void) if (resolved_path) { zend_persistent_script *incl = zend_hash_find_ptr(preload_scripts, resolved_path); - if (incl && incl->empty) { + if (incl && incl->empty && opline->result_type == IS_UNUSED) { MAKE_NOP(opline); } else { if (!IS_ABSOLUTE_PATH(Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), Z_STRLEN_P(RT_CONSTANT(opline, opline->op1)))) { From b16fc350a49c2797039d5ecf8341f6a2b5a6b29a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 14 Dec 2021 15:31:53 +0300 Subject: [PATCH 45/96] Move common code into helper --- Zend/zend_execute.c | 7 +++ Zend/zend_vm_def.h | 17 ++---- Zend/zend_vm_execute.h | 136 +++++++++++++++-------------------------- 3 files changed, 61 insertions(+), 99 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 4282023909ba0..a245db9835379 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1431,6 +1431,10 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zv zval *z; zval rv, res; + GC_ADDREF(obj); + if (property && UNEXPECTED(Z_ISUNDEF_P(property))) { + property = ZVAL_UNDEFINED_OP2(); + } value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); if ((z = obj->handlers->read_dimension(obj, property, BP_VAR_R, &rv)) != NULL) { @@ -1451,6 +1455,9 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zend_object *obj, zv } } FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } } static zend_never_inline void zend_binary_assign_op_typed_ref(zend_reference *ref, zval *value OPLINE_DC EXECUTE_DATA_DC) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4199c090e266b..856091fcd5a4f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1150,6 +1150,7 @@ ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP) USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); @@ -1157,19 +1158,20 @@ ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP) if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { ZEND_VM_C_LABEL(assign_dim_op_array): SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); ZEND_VM_C_LABEL(assign_dim_op_new_array): dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if (OP2_TYPE == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); ZEND_VM_C_GOTO(assign_dim_op_ret_null); } } else { if (OP2_TYPE == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { ZEND_VM_C_GOTO(assign_dim_op_ret_null); @@ -1205,19 +1207,12 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array): if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); - if (OP2_TYPE == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 67c6eca46983c..362cd8436aeb2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22392,6 +22392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -22399,19 +22400,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_CONST == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -22447,19 +22449,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -25047,6 +25042,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -25054,19 +25050,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -25102,19 +25099,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -27340,6 +27330,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -27347,19 +27338,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = NULL; if (IS_UNUSED == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_UNUSED == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -27395,19 +27387,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_ if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -29181,6 +29166,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); @@ -29188,19 +29174,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = EX_VAR(opline->op2.var); if (IS_CV == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_CV == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -29236,19 +29223,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HAND if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -39889,6 +39869,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); @@ -39896,19 +39877,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = RT_CONSTANT(opline, opline->op2); if (IS_CONST == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_CONST == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -39944,19 +39926,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HA if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -43623,6 +43598,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); @@ -43630,19 +43606,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -43678,19 +43655,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -46492,6 +46462,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); @@ -46499,19 +46470,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = NULL; if (IS_UNUSED == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_UNUSED == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -46547,19 +46519,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_H if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { @@ -48864,6 +48829,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL USE_OPLINE zval *var_ptr; zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); @@ -48871,19 +48837,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { assign_dim_op_array: SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); assign_dim_op_new_array: dim = EX_VAR(opline->op2.var); if (IS_CV == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval)); + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { if (IS_CV == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(Z_ARRVAL_P(container), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } if (UNEXPECTED(!var_ptr)) { goto assign_dim_op_ret_null; @@ -48919,19 +48886,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDL if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - HashTable *ht; zend_uchar old_type; if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { From 75b2973974414fb52a19c0466c8f2afc2081eb49 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 15 Dec 2021 12:20:37 +0300 Subject: [PATCH 46/96] Fix array clobbering by user error handler Fixes oss-fuzz #42363 --- Zend/tests/falsetoarray_003.phpt | 16 ++++++++++++++++ Zend/zend_vm_def.h | 5 ++++- Zend/zend_vm_execute.h | 25 ++++++++++++++++++++----- 3 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/falsetoarray_003.phpt diff --git a/Zend/tests/falsetoarray_003.phpt b/Zend/tests/falsetoarray_003.phpt new file mode 100644 index 0000000000000..11b32771e1fc1 --- /dev/null +++ b/Zend/tests/falsetoarray_003.phpt @@ -0,0 +1,16 @@ +--TEST-- +Autovivification of false to array with data clobbering by error handler +--FILE-- + +DONE +--EXPECTF-- +Err: Implicit conversion from float %f to int loses precision +Err: Undefined array key %i +DONE diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 856091fcd5a4f..6920bc7632a2f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -9670,7 +9670,10 @@ ZEND_VM_C_LABEL(fetch_dim_r_index_array): if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC); + FREE_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 362cd8436aeb2..42f5310cd026e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8318,7 +8318,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); @@ -16126,7 +16129,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); @@ -16178,7 +16184,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); @@ -42928,7 +42937,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); @@ -42980,7 +42992,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_ if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { offset = Z_LVAL_P(dim); } else { - offset = zval_get_long_ex(dim, /* is_strict */ true); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } ht = Z_ARRVAL_P(container); ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); From 49380b59d28f6ad7f897bf6189ba2e1ad78d4c8b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 15 Dec 2021 11:47:44 +0100 Subject: [PATCH 47/96] Fix #81679: Tracing JIT crashes on reattaching When a new process reattaches to OPcache, tracing JIT causes segfaults, because each new process allocates its own `zend_jit_traces` and `zend_jit_exit_groups` in SHM, although these need to be shared between all processes. We solve that by only allocating these structs for the first process, and store the pointers in `accel_shared_globals`, so we can reassign them when a new process reattaches. Closes GH-7776. --- NEWS | 3 +++ ext/opcache/ZendAccelerator.h | 4 ++++ ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/jit/zend_jit_trace.c | 37 +++++++++++++++++++++----------- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 6f1a19ddd8a76..ddc18717a3294 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ PHP NEWS . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second call). (cmb) +- OPcache: + . Fixed bug #81679 (Tracing JIT crashes on reattaching). (cmb) + - PDO_PGSQL: . Fixed error message allocation of PDO PgSQL. (SATO Kentaro) diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index b9e3f2a81de83..610decd7995db 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -285,6 +285,10 @@ typedef struct _zend_accel_shared_globals { /* uninitialized HashTable Support */ uint32_t uninitialized_bucket[-HT_MIN_MASK]; + /* Tracing JIT */ + void *jit_traces; + const void **jit_exit_groups; + /* Interned Strings Support (must be the last element) */ zend_string_table interned_strings; } zend_accel_shared_globals; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index bbe879b9fddd2..fdffcbc1034c7 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -4390,7 +4390,7 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, zend_bool reattached) #endif } - if (zend_jit_trace_startup() != SUCCESS) { + if (zend_jit_trace_startup(reattached) != SUCCESS) { return FAILURE; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index fa29a03997740..dd37f33ad6853 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -48,20 +48,33 @@ static zend_always_inline const char *zend_jit_trace_star_desc(uint8_t trace_fla } } -static int zend_jit_trace_startup(void) +static int zend_jit_trace_startup(zend_bool reattached) { - zend_jit_traces = (zend_jit_trace_info*)zend_shared_alloc(sizeof(zend_jit_trace_info) * JIT_G(max_root_traces)); - if (!zend_jit_traces) { - return FAILURE; - } - zend_jit_exit_groups = (const void**)zend_shared_alloc(sizeof(void*) * (ZEND_JIT_TRACE_MAX_EXITS/ZEND_JIT_EXIT_POINTS_PER_GROUP)); - if (!zend_jit_exit_groups) { - return FAILURE; + if (!reattached) { + zend_jit_traces = (zend_jit_trace_info*)zend_shared_alloc(sizeof(zend_jit_trace_info) * JIT_G(max_root_traces)); + if (!zend_jit_traces) { + return FAILURE; + } + zend_jit_exit_groups = (const void**)zend_shared_alloc(sizeof(void*) * (ZEND_JIT_TRACE_MAX_EXITS/ZEND_JIT_EXIT_POINTS_PER_GROUP)); + if (!zend_jit_exit_groups) { + return FAILURE; + } + ZEND_JIT_TRACE_NUM = 1; + ZEND_JIT_COUNTER_NUM = 0; + ZEND_JIT_EXIT_NUM = 0; + ZEND_JIT_EXIT_COUNTERS = 0; + ZCSG(jit_traces) = zend_jit_traces; + ZCSG(jit_exit_groups) = zend_jit_exit_groups; + } else { + zend_jit_traces = ZCSG(jit_traces); + if (!zend_jit_traces) { + return FAILURE; + } + zend_jit_exit_groups = ZCSG(jit_exit_groups); + if (!zend_jit_exit_groups) { + return FAILURE; + } } - ZEND_JIT_TRACE_NUM = 1; - ZEND_JIT_COUNTER_NUM = 0; - ZEND_JIT_EXIT_NUM = 0; - ZEND_JIT_EXIT_COUNTERS = 0; memset(&dummy_op_array, 0, sizeof(dummy_op_array)); dummy_op_array.fn_flags = ZEND_ACC_DONE_PASS_TWO; From 66306030ad26da49bbc6c07624fa3b4b1f1d9757 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 17 Dec 2021 12:31:48 +0300 Subject: [PATCH 48/96] JIT: Fix incorrect type store elimination Fixes oss-fuzz #42388 --- ext/opcache/jit/zend_jit_trace.c | 16 +++++----- ext/opcache/tests/jit/assign_048.phpt | 43 +++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 ext/opcache/tests/jit/assign_048.phpt diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index dd37f33ad6853..9a310d3e35197 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4609,15 +4609,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par op2_info = OP2_INFO(); CHECK_OP2_TRACE_TYPE(); op1_info = OP1_INFO(); - if (ssa->vars[ssa_op->op1_use].no_val) { - if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG - || (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_DOUBLE) { - if (STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_LONG - && STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_DOUBLE) { - /* type may be not set */ - op1_info |= MAY_BE_NULL; - } - } + if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_LONG + || (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_GUARD)) == MAY_BE_DOUBLE) { + if (STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_LONG + && STACK_MEM_TYPE(stack, EX_VAR_TO_NUM(opline->op1.var)) != IS_DOUBLE) { + /* type may be not set */ + op1_info |= MAY_BE_NULL; + } } CHECK_OP1_TRACE_TYPE(); op1_def_info = OP1_DEF_INFO(); diff --git a/ext/opcache/tests/jit/assign_048.phpt b/ext/opcache/tests/jit/assign_048.phpt new file mode 100644 index 0000000000000..a6bcf14933a78 --- /dev/null +++ b/ext/opcache/tests/jit/assign_048.phpt @@ -0,0 +1,43 @@ +--TEST-- +JIT ASSIGN: incorrect type store elimination +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +opcache.protect_memory=1 +opcache.optimization_level=0x7FFEBFFF +--FILE-- + +DONE +--EXPECTF-- +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 + +Warning: Undefined variable $a in %sassign_048.php on line 7 +DONE From 2745cd99973a5b422c66d62b9d9229da22e82a34 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 17 Dec 2021 12:49:58 +0300 Subject: [PATCH 49/96] Fix array clobbering by user error handler Fixes oss-fuzz #42503 --- ext/opcache/jit/zend_jit_helpers.c | 53 +++++++++++++++++++++- ext/opcache/tests/jit/fetch_dim_w_003.phpt | 17 +++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/fetch_dim_w_003.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index e7cd2796b589d..5257a6af9c819 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -730,10 +730,61 @@ static zval* ZEND_FASTCALL zend_jit_fetch_dim_w_helper(zend_array *ht, zval *dim offset_key = ZSTR_EMPTY_ALLOC(); goto str_index; case IS_DOUBLE: - hval = zend_dval_to_lval_safe(Z_DVAL_P(dim)); + hval = zend_dval_to_lval(Z_DVAL_P(dim)); + if (!zend_is_long_compatible(Z_DVAL_P(dim), hval)) { + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); + zend_incompatible_double_to_long_error(Z_DVAL_P(dim)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; + } + } goto num_index; case IS_RESOURCE: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_use_resource_as_offset(dim); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return NULL; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return NULL; + } hval = Z_RES_HANDLE_P(dim); goto num_index; case IS_FALSE: diff --git a/ext/opcache/tests/jit/fetch_dim_w_003.phpt b/ext/opcache/tests/jit/fetch_dim_w_003.phpt new file mode 100644 index 0000000000000..33fc2ccbb8459 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_w_003.phpt @@ -0,0 +1,17 @@ +--TEST-- +JIT FETCH_DIM_W: 003 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 3587e13ab3dc256ff2ebfe0f7aabc46bc5441cb7 Mon Sep 17 00:00:00 2001 From: Yifan Tong Date: Sun, 19 Dec 2021 05:39:54 +0100 Subject: [PATCH 50/96] Fix FILTER_FLAG_NO_RES_RANGE flag `2001:10::/28` is a reserved IPv6 range. But there's a typo in GH-7476, which caused IPv6 address like `240b:0010::1` will be filtered by the flag `FILTER_FLAG_NO_RES_RANGE`. http://www.faqs.org/rfcs/rfc6890.html Closes GH-7790. --- NEWS | 3 +++ ext/filter/logical_filters.c | 2 +- ext/filter/tests/bug47435.phpt | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index ddc18717a3294..ae1d224b6268d 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,9 @@ PHP NEWS . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) +- Filter: + . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) + - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index 6bf5e9a7cfb1d..1bf7c00d13c68 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -929,7 +929,7 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ && ip[4] == 0 && ip[5] == 0 && ip[6] == 0 && (ip[7] == 0 || ip[7] == 1)) || (ip[0] == 0x5f) || (ip[0] >= 0xfe80 && ip[0] <= 0xfebf) - || ((ip[0] == 0x2001 && ip[1] == 0x0db8) || (ip[1] >= 0x0010 && ip[1] <= 0x001f)) + || (ip[0] == 0x2001 && (ip[1] == 0x0db8 || (ip[1] >= 0x0010 && ip[1] <= 0x001f))) || (ip[0] == 0x3ff3) ) { RETURN_VALIDATION_FAILED diff --git a/ext/filter/tests/bug47435.phpt b/ext/filter/tests/bug47435.phpt index e17142aad963d..1e1c466702408 100644 --- a/ext/filter/tests/bug47435.phpt +++ b/ext/filter/tests/bug47435.phpt @@ -14,6 +14,10 @@ var_dump(filter_var("fe80:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); var_dump(filter_var("fe80:5:6::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); var_dump(filter_var("2001:0db8::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("2001:0010::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); +var_dump(filter_var("2001:0010::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); +var_dump(filter_var("240b:0010::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); +var_dump(filter_var("240b:0010::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("5f::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); var_dump(filter_var("5f::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 | FILTER_FLAG_NO_RES_RANGE)); var_dump(filter_var("3ff3::1", FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)); @@ -30,6 +34,10 @@ string(11) "fe80:5:6::1" bool(false) string(12) "2001:0db8::1" bool(false) +string(12) "2001:0010::1" +bool(false) +string(12) "240b:0010::1" +string(12) "240b:0010::1" string(5) "5f::1" bool(false) string(7) "3ff3::1" From 1481d66343a5acfc682e846eae14bf71d135ae7a Mon Sep 17 00:00:00 2001 From: Joe Rowell Date: Fri, 17 Dec 2021 10:20:10 +0000 Subject: [PATCH 51/96] [ci skip] Fix "The Mysterious PHP RFC Process" link. Closes GH-7785. --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df94bd50e5f69..450c25fddbd66 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,7 +80,7 @@ repository. Mailing list subscription is explained on the [mailing lists page](https://www.php.net/mailing-lists.php). You may also want to read -[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/entry/the_mysterious_php_rfc_process) +[The Mysterious PHP RFC Process](https://blogs.oracle.com/opal/post/the-mysterious-php-rfc-process-and-how-you-can-change-the-web) for additional notes on the best way to approach submitting an RFC. ## Writing tests From f18bb2477fba864d20d2c3b7422e5b9ce88f1f79 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 20 Dec 2021 11:40:11 +0300 Subject: [PATCH 52/96] Fix type inference for INIT_ARRAY with invalid index Fixes oss-fuzz #42568 --- ext/opcache/Optimizer/zend_inference.c | 4 +++- ext/opcache/tests/opt/inference_002.phpt | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/opt/inference_002.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index e4bb7ec3454a9..feb469303c497 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -3002,7 +3002,9 @@ static zend_always_inline int _zend_update_type_info( if (ssa_op->result_use >= 0) { tmp |= ssa_var_info[ssa_op->result_use].type; } - if (opline->op1_type != IS_UNUSED) { + if (opline->op1_type != IS_UNUSED + && (opline->op2_type == IS_UNUSED + || (t2 & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_RESOURCE|MAY_BE_STRING)))) { tmp |= (t1 & MAY_BE_ANY) << MAY_BE_ARRAY_SHIFT; if (t1 & MAY_BE_UNDEF) { tmp |= MAY_BE_ARRAY_OF_NULL; diff --git a/ext/opcache/tests/opt/inference_002.phpt b/ext/opcache/tests/opt/inference_002.phpt new file mode 100644 index 0000000000000..70412426c2fcc --- /dev/null +++ b/ext/opcache/tests/opt/inference_002.phpt @@ -0,0 +1,15 @@ +--TEST-- +Type inference 002: Type inference for INIT_ARRAY with invalid index +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +&$x]); +?> +--EXPECTF-- +Fatal error: Uncaught TypeError: Illegal offset type in %sinference_002.php:2 +Stack trace: +#0 {main} + thrown in %sinference_002.php on line 2 \ No newline at end of file From 7c674e1aa7d688086aace0cc3e5bb7635b595417 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 20 Dec 2021 12:48:48 +0300 Subject: [PATCH 53/96] JIT: Fix register clobbering Fixes oss-fuzz #42657 --- ext/opcache/jit/zend_jit_x86.dasc | 63 ++++++++++++++++++++---------- ext/opcache/tests/jit/add_012.phpt | 19 +++++++++ 2 files changed, 61 insertions(+), 21 deletions(-) create mode 100644 ext/opcache/tests/jit/add_012.phpt diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index cb41c6a2656e9..543d78a1dd278 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -772,17 +772,12 @@ static void* dasm_labels[zend_lb_MAX]; || } |.endmacro -|.macro LONG_OP, long_ins, reg, addr +|.macro LONG_OP, long_ins, reg, addr, tmp_reg || if (Z_MODE(addr) == IS_CONST_ZVAL) { | .if X64 || if (!IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(addr)))) { -|| if (reg != ZREG_R0) { -| mov64 r0, Z_LVAL_P(Z_ZV(addr)) -| long_ins Ra(reg), r0 -|| } else { -| mov64 r1, Z_LVAL_P(Z_ZV(addr)) -| long_ins Ra(reg), r1 -|| } +| mov64 tmp_reg, Z_LVAL_P(Z_ZV(addr)) +| long_ins Ra(reg), tmp_reg || } else { | long_ins Ra(reg), Z_LVAL_P(Z_ZV(addr)) || } @@ -862,25 +857,25 @@ static void* dasm_labels[zend_lb_MAX]; || } |.endmacro -|.macro LONG_MATH, opcode, reg, addr +|.macro LONG_MATH, opcode, reg, addr, tmp_reg || switch (opcode) { || case ZEND_ADD: -| LONG_OP add, reg, addr +| LONG_OP add, reg, addr, Ra(tmp_reg) || break; || case ZEND_SUB: -| LONG_OP sub, reg, addr +| LONG_OP sub, reg, addr, Ra(tmp_reg) || break; || case ZEND_MUL: -| LONG_OP imul, reg, addr +| LONG_OP imul, reg, addr, Ra(tmp_reg) || break; || case ZEND_BW_OR: -| LONG_OP or, reg, addr +| LONG_OP or, reg, addr, Ra(tmp_reg) || break; || case ZEND_BW_AND: -| LONG_OP and, reg, addr +| LONG_OP and, reg, addr, Ra(tmp_reg) || break; || case ZEND_BW_XOR: -| LONG_OP xor, reg, addr +| LONG_OP xor, reg, addr, Ra(tmp_reg) || break; || default: || ZEND_UNREACHABLE(); @@ -4390,7 +4385,16 @@ static int zend_jit_math_long_long(dasm_State **Dst, } else if (same_ops && opcode != ZEND_DIV) { | LONG_MATH_REG opcode, Ra(result_reg), Ra(result_reg) } else { - | LONG_MATH opcode, result_reg, op2_addr + zend_reg tmp_reg; + + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { + tmp_reg = ZREG_R1; + } else if (result_reg != ZREG_R0) { + tmp_reg = ZREG_R0; + } else { + tmp_reg = ZREG_R1; + } + | LONG_MATH opcode, result_reg, op2_addr, tmp_reg } } if (may_overflow) { @@ -5117,12 +5121,20 @@ static int zend_jit_long_math_helper(dasm_State **Dst, } else if (zend_long_is_power_of_two(op2_lval) && op1_range && op1_range->min >= 0) { zval tmp; zend_jit_addr tmp_addr; + zend_reg tmp_reg; /* Optimisation for mod of power of 2 */ ZVAL_LONG(&tmp, op2_lval - 1); tmp_addr = ZEND_ADDR_CONST_ZVAL(&tmp); + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { + tmp_reg = ZREG_R1; + } else if (result_reg != ZREG_R0) { + tmp_reg = ZREG_R0; + } else { + tmp_reg = ZREG_R1; + } | GET_ZVAL_LVAL result_reg, op1_addr - | LONG_MATH ZEND_BW_AND, result_reg, tmp_addr + | LONG_MATH ZEND_BW_AND, result_reg, tmp_addr, tmp_reg } else { if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { | mov aword T1, r0 // save @@ -5210,8 +5222,17 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | GET_ZVAL_LVAL result_reg, op1_addr | LONG_MATH_REG opcode, Ra(result_reg), Ra(result_reg) } else { + zend_reg tmp_reg; + + if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_R0) { + tmp_reg = ZREG_R1; + } else if (result_reg != ZREG_R0) { + tmp_reg = ZREG_R0; + } else { + tmp_reg = ZREG_R1; + } | GET_ZVAL_LVAL result_reg, op1_addr - | LONG_MATH opcode, result_reg, op2_addr + | LONG_MATH opcode, result_reg, op2_addr, tmp_reg } if (Z_MODE(res_addr) != IS_REG || Z_REG(res_addr) != result_reg) { @@ -7025,13 +7046,13 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 0) { | test Ra(Z_REG(op1_addr)), Ra(Z_REG(op1_addr)) } else { - | LONG_OP cmp, Z_REG(op1_addr), op2_addr + | LONG_OP cmp, Z_REG(op1_addr), op2_addr, r0 } } else if (Z_MODE(op2_addr) == IS_REG) { if (Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op1_addr)) == 0) { | test Ra(Z_REG(op2_addr)), Ra(Z_REG(op2_addr)) } else { - | LONG_OP cmp, Z_REG(op2_addr), op1_addr + | LONG_OP cmp, Z_REG(op2_addr), op1_addr, r0 } swap = 1; } else if (Z_MODE(op1_addr) == IS_CONST_ZVAL && Z_MODE(op2_addr) != IS_CONST_ZVAL) { @@ -7044,7 +7065,7 @@ static int zend_jit_cmp_long_long(dasm_State **Dst, if (Z_MODE(op2_addr) == IS_CONST_ZVAL && Z_LVAL_P(Z_ZV(op2_addr)) == 0) { | test r0, r0 } else { - | LONG_OP cmp, ZREG_R0, op2_addr + | LONG_OP cmp, ZREG_R0, op2_addr, r0 } } diff --git a/ext/opcache/tests/jit/add_012.phpt b/ext/opcache/tests/jit/add_012.phpt new file mode 100644 index 0000000000000..645f8f4bdd9b5 --- /dev/null +++ b/ext/opcache/tests/jit/add_012.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT ADD: 012 register allocation for 64-bit constant +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--SKIPIF-- + +--FILE-- + +DONE +--EXPECT-- +DONE \ No newline at end of file From e004e844f74998878853517d900f99dbc1e9db3d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 20 Dec 2021 15:06:32 +0300 Subject: [PATCH 54/96] Fix incorrect optimization of ASSIGN_OP that may lead to memory leak Fixes oss-fuzz #42506 --- ext/opcache/Optimizer/dfa_pass.c | 13 +++++++--- ext/opcache/tests/opt/assign_op_001.phpt | 30 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/opt/assign_op_001.phpt diff --git a/ext/opcache/Optimizer/dfa_pass.c b/ext/opcache/Optimizer/dfa_pass.c index 823eccdb4f23f..496ff5618e175 100644 --- a/ext/opcache/Optimizer/dfa_pass.c +++ b/ext/opcache/Optimizer/dfa_pass.c @@ -323,7 +323,7 @@ static inline zend_bool can_elide_return_type_check( } static zend_bool opline_supports_assign_contraction( - zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) { + zend_op_array *op_array, zend_ssa *ssa, zend_op *opline, int src_var, uint32_t cv_var) { if (opline->opcode == ZEND_NEW) { /* see Zend/tests/generators/aborted_yield_during_new.phpt */ return 0; @@ -357,6 +357,13 @@ static zend_bool opline_supports_assign_contraction( return opline->op1_type != IS_CV || opline->op1.var != cv_var; } + if (opline->opcode == ZEND_ASSIGN_OP + && opline->op1_type == IS_CV + && opline->op1.var == cv_var + && zend_may_throw(opline, &ssa->ops[ssa->vars[src_var].definition], op_array, ssa)) { + return 0; + } + return 1; } @@ -1310,7 +1317,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && !ssa->vars[src_var].phi_use_chain && !ssa->vars[src_var].sym_use_chain && opline_supports_assign_contraction( - ssa, &op_array->opcodes[ssa->vars[src_var].definition], + op_array, ssa, &op_array->opcodes[ssa->vars[src_var].definition], src_var, opline->result.var) && !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->result.var), ssa->vars[src_var].definition+1, op_1) @@ -1467,7 +1474,7 @@ void zend_dfa_optimize_op_array(zend_op_array *op_array, zend_optimizer_ctx *ctx && !ssa->vars[src_var].phi_use_chain && !ssa->vars[src_var].sym_use_chain && opline_supports_assign_contraction( - ssa, &op_array->opcodes[ssa->vars[src_var].definition], + op_array, ssa, &op_array->opcodes[ssa->vars[src_var].definition], src_var, opline->op1.var) && !variable_defined_or_used_in_range(ssa, EX_VAR_TO_NUM(opline->op1.var), ssa->vars[src_var].definition+1, op_1) diff --git a/ext/opcache/tests/opt/assign_op_001.phpt b/ext/opcache/tests/opt/assign_op_001.phpt new file mode 100644 index 0000000000000..b9db4202b46c0 --- /dev/null +++ b/ext/opcache/tests/opt/assign_op_001.phpt @@ -0,0 +1,30 @@ +--TEST-- +ASSIGN_OP 001: Incrrect optimization of ASSIGN_OP may lead to memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- + +--EXPECTF-- +Warning: Undefined variable $a in %sassign_op_001.php on line 4 + +Warning: Undefined variable $a in %sassign_op_001.php on line 4 + +Warning: Undefined array key "b" in %sassign_op_001.php on line 7 + +Fatal error: Uncaught TypeError: Unsupported operand types: array + bool in %sassign_op_001.php:4 +Stack trace: +#0 %sassign_op_001.php(10): test() +#1 {main} + thrown in %sassign_op_001.php on line 4 \ No newline at end of file From 069bbf3e8009795bfeec2d46cd4bb39d6907d29a Mon Sep 17 00:00:00 2001 From: Petr Sumbera Date: Tue, 14 Dec 2021 10:57:22 +0100 Subject: [PATCH 55/96] Fix zend_fibers.c build with ZEND_FIBER_UCONTEXT Avoids (Solaris SPARC) issue: zend_fibers.c:77:9: error: unknown type name 'ucontext_t' Closes GH-7773. --- NEWS | 1 + Zend/zend_fibers.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index af3a74ae1f293..a3b9a4c6c00a0 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,7 @@ PHP NEWS (cmb) . Fixed bug GH-7757 (Multi-inherited final constant causes fatal error). (cmb) + . Fixed zend_fibers.c build with ZEND_FIBER_UCONTEXT. (Petr Sumbera) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/zend_fibers.c b/Zend/zend_fibers.c index 92ae9b8837cb7..dd06f86ae8da6 100644 --- a/Zend/zend_fibers.c +++ b/Zend/zend_fibers.c @@ -32,6 +32,10 @@ # include #endif +#ifdef ZEND_FIBER_UCONTEXT +# include +#endif + #ifndef ZEND_WIN32 # include # include @@ -118,7 +122,6 @@ static zend_always_inline void zend_fiber_restore_vm_state(zend_fiber_vm_state * } #ifdef ZEND_FIBER_UCONTEXT -# include ZEND_TLS zend_fiber_transfer *transfer_data; #else /* boost_context_data is our customized definition of struct transfer_t as From f07c1935839bf87e9d5a26a82a0ed8747c4f178f Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Sun, 5 Dec 2021 19:29:00 +0200 Subject: [PATCH 56/96] mb_convert_encoding will not auto-detect input string as UUEncode, Base64, QPrint In a2bc57e0e5, mb_detect_encoding was modified to ensure it would never return 'UUENCODE', 'QPrint', or other non-encodings as the "detected text encoding". Before mb_detect_encoding was enhanced so that it could detect any supported text encoding, those were never returned, and they are not desired. Actually, we want to eventually remove them completely from mbstring, since PHP already contains other implementations of UUEncode, QPrint, Base64, and HTML entities. For more clarity on why we need to suppress UUEncode, etc. from being detected by mb_detect_encoding, the existing UUEncode implementation in mbstring *never* treats any input as erroneous. It just accepts everything. This means that it would *always* be treated as a valid choice by mb_detect_encoding, and would be returned in many, many cases where the input is obviously not UUEncoded. It turns out that the form of mb_convert_encoding where the user passes multiple candidate encodings (and mbstring auto-detects which one to use) was also affected by the same issue. Apply the same fix. --- ext/mbstring/mbstring.c | 38 ++++++++++++--------- ext/mbstring/tests/mb_convert_encoding.phpt | 25 +++++--------- 2 files changed, 30 insertions(+), 33 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 92a3d865bbd1d..a9bbb3e47e1a5 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2491,6 +2491,23 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons } /* }}} */ +static void remove_non_encodings_from_elist(const mbfl_encoding **elist, size_t *size) +{ + /* mbstring supports some 'text encodings' which aren't really text encodings + * at all, but really 'byte encodings', like Base64, QPrint, and so on. + * These should never be returned by `mb_detect_encoding`. */ + int shift = 0; + for (int i = 0; i < *size; i++) { + const mbfl_encoding *encoding = elist[i]; + if (encoding->no_encoding <= mbfl_no_encoding_charset_min) { + shift++; /* Remove this encoding from the list */ + } else if (shift) { + elist[i - shift] = encoding; + } + } + *size -= shift; +} + /* {{{ Returns converted string in desired encoding */ PHP_FUNCTION(mb_convert_encoding) { @@ -2531,6 +2548,10 @@ PHP_FUNCTION(mb_convert_encoding) free_from_encodings = 0; } + if (num_from_encodings > 1) { + remove_non_encodings_from_elist(from_encodings, &num_from_encodings); + } + if (!num_from_encodings) { efree(ZEND_VOIDP(from_encodings)); zend_argument_value_error(3, "must specify at least one encoding"); @@ -2664,23 +2685,6 @@ PHP_FUNCTION(mb_strtolower) } /* }}} */ -static void remove_non_encodings_from_elist(const mbfl_encoding **elist, size_t *size) -{ - /* mbstring supports some 'text encodings' which aren't really text encodings - * at all, but really 'byte encodings', like Base64, QPrint, and so on. - * These should never be returned by `mb_detect_encoding`. */ - int shift = 0; - for (int i = 0; i < *size; i++) { - const mbfl_encoding *encoding = elist[i]; - if (encoding->no_encoding <= mbfl_no_encoding_charset_min) { - shift++; /* Remove this encoding from the list */ - } else if (shift) { - elist[i - shift] = encoding; - } - } - *size -= shift; -} - /* {{{ Encodings of the given string is returned (as a string) */ PHP_FUNCTION(mb_detect_encoding) { diff --git a/ext/mbstring/tests/mb_convert_encoding.phpt b/ext/mbstring/tests/mb_convert_encoding.phpt index 257873f313079..2c8353e638fe4 100644 --- a/ext/mbstring/tests/mb_convert_encoding.phpt +++ b/ext/mbstring/tests/mb_convert_encoding.phpt @@ -9,33 +9,24 @@ mbstring.language=Japanese 'JIS', 1=>'UTF-8', 2=>'EUC-JP', 3=>'SJIS'); +$a = ['JIS', 'UTF-8', 'EUC-JP', 'SJIS']; $s = $jis; $s = bin2hex(mb_convert_encoding($s, 'EUC-JP', $a)); print("EUC-JP: $s\n"); // EUC-JP @@ -69,6 +59,8 @@ $s = $euc_jp; $s = mb_convert_encoding($s, 'JIS', $a); print("JIS: ".base64_encode($s)."\n"); // JIS +// Regression test for bug #81676 +echo "UTF-8: " . mb_convert_encoding('test', 'UTF-8', mb_list_encodings()), "\n"; // Using Detect Order echo "== DETECT ORDER ==\n"; @@ -117,6 +109,7 @@ JIS: GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg== EUC-JP: c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 SJIS: k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg== JIS: GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4IzkhIxsoQg== +UTF-8: test == DETECT ORDER == EUC-JP: c6fccbdcb8eca5c6a5ada5b9a5c8a4c7a4b9a1a33031323334a3b5a3b6a3b7a3b8a3b9a1a3 SJIS: k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg== From 6d5922bed5930b3ed453e9364c16ccd33ff45a86 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 20 Dec 2021 23:52:46 +0300 Subject: [PATCH 57/96] JIT: Fix incorrect JIT prologur size for CLANG/x86 build Fixes oss-fuzz #42724 --- ext/opcache/jit/zend_jit_x86.dasc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 543d78a1dd278..48527b1076c04 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3440,7 +3440,7 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, #if defined(__x86_64__) || defined(_M_X64) prologue_size = 17; #else - prologue_size = 12; + prologue_size = 13; #endif } link_addr = (const void*)((const char*)t->code_start + prologue_size); From cb10ac1d53249df9c367815ab60f346b57f4d015 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 21 Dec 2021 00:02:45 +0300 Subject: [PATCH 58/96] Fixed compilation warning --- ext/opcache/jit/zend_jit_x86.dasc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 48527b1076c04..54b1f1ce09c90 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -4395,6 +4395,7 @@ static int zend_jit_math_long_long(dasm_State **Dst, tmp_reg = ZREG_R1; } | LONG_MATH opcode, result_reg, op2_addr, tmp_reg + (void)tmp_reg; } } if (may_overflow) { @@ -5135,6 +5136,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, } | GET_ZVAL_LVAL result_reg, op1_addr | LONG_MATH ZEND_BW_AND, result_reg, tmp_addr, tmp_reg + (void)tmp_reg; } else { if (Z_MODE(res_addr) == IS_MEM_ZVAL && Z_REG(res_addr) == ZREG_RAX) { | mov aword T1, r0 // save @@ -5233,6 +5235,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, } | GET_ZVAL_LVAL result_reg, op1_addr | LONG_MATH opcode, result_reg, op2_addr, tmp_reg + (void)tmp_reg; } if (Z_MODE(res_addr) != IS_REG || Z_REG(res_addr) != result_reg) { From 62bcb31706975b383d7911d529c6e88a7b8d9d3b Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 11 Dec 2021 09:07:42 +0000 Subject: [PATCH 59/96] zend gdb detection fix on FreeBSD. --- Zend/zend_gdb.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/Zend/zend_gdb.c b/Zend/zend_gdb.c index ce6dc6a7850f9..8ba40f01d22f9 100644 --- a/Zend/zend_gdb.c +++ b/Zend/zend_gdb.c @@ -25,6 +25,11 @@ #include #include +#if defined(__FreeBSD__) +# include +# include +#endif + enum { ZEND_GDBJIT_NOACTION, ZEND_GDBJIT_REGISTER, @@ -105,6 +110,7 @@ ZEND_API void zend_gdb_unregister_all(void) ZEND_API bool zend_gdb_present(void) { bool ret = 0; +#if defined(__linux__) /* netbsd while having this procfs part, does not hold the tracer pid */ int fd = open("/proc/self/status", O_RDONLY); if (fd > 0) { @@ -136,6 +142,17 @@ ZEND_API bool zend_gdb_present(void) close(fd); } +#elif defined(__FreeBSD__) + struct kinfo_proc *proc = kinfo_getproc(getpid()); + + if (proc) { + if ((proc->ki_flag & P_TRACED) != 0) { + struct kinfo_proc *dbg = kinfo_getproc(proc->ki_tracer); + + ret = (dbg && strstr(dbg->ki_comm, "gdb")); + } + } +#endif return ret; } From 51647eb23e61d214cdeb4167fcee1e2c38924bfe Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 21 Nov 2021 19:57:07 +0000 Subject: [PATCH 60/96] socket: ancillary credentials build fix for non linux systems. for systems using SO_PASSCRED sockopt flag but not using ucred struct. --- ext/sockets/config.m4 | 28 ++++++++++++++++++++++++++++ ext/sockets/conversions.c | 9 ++++++++- ext/sockets/sendrecvmsg.c | 9 +++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index b78186ee11ba6..d4f92082c3b2d 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -62,6 +62,34 @@ if test "$PHP_SOCKETS" != "no"; then AC_DEFINE(HAVE_AI_IDN,1,[Whether you have AI_IDN]) fi + dnl Check for struct ucred + dnl checking the header is not enough (eg DragonFlyBSD) + AC_CACHE_CHECK([if ancillary credentials uses ucred],[ac_cv_ucred], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[struct ucred u = {.gid = 0};]])], + [ac_cv_ucred=yes], [ac_cv_ucred=no]) + ]) + + if test "$ac_cv_ucred" = yes; then + AC_DEFINE(ANC_CREDS_UCRED,1,[Uses ucred struct]) + fi + + dnl Check for struct cmsgcred + AC_CACHE_CHECK([if ancillary credentials uses cmsgcred],[ac_cv_cmsgcred], + [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include + ]], [[struct cmsgcred c = {0};]])], + [ac_cv_cmsgcred=yes], [ac_cv_cmsgcred=no]) + ]) + + if test "$ac_cv_cmsgcred" = yes; then + AC_DEFINE(ANC_CREDS_CMSGCRED,1,[Uses cmsgcred struct]) + fi + + PHP_SOCKETS_CFLAGS=-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 case $host_alias in *darwin*) PHP_SOCKETS_CFLAGS="$PHP_SOCKETS_CFLAGS -D__APPLE_USE_RFC_3542" diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c index 4eaa217b73805..ecf3fb47b508d 100644 --- a/ext/sockets/conversions.c +++ b/ext/sockets/conversions.c @@ -1297,13 +1297,20 @@ void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx) } #endif -/* CONVERSIONS for struct ucred */ +/* CONVERSIONS for struct ucred/cmsgcred */ #ifdef SO_PASSCRED static const field_descriptor descriptors_ucred[] = { +#if defined(ANC_CREDS_UCRED) {"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t}, {"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t}, /* assume the type gid_t is the same as uid_t: */ {"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t}, +#elif defined(ANC_CREDS_CMSGCRED) + {"pid", sizeof("pid"), 1, offsetof(struct cmsgcred, cmcred_pid), from_zval_write_pid_t, to_zval_read_pid_t}, + {"uid", sizeof("uid"), 1, offsetof(struct cmsgcred, cmcred_uid), from_zval_write_uid_t, to_zval_read_uid_t}, + /* assume the type gid_t is the same as uid_t: */ + {"gid", sizeof("gid"), 1, offsetof(struct cmsgcred, cmcred_gid), from_zval_write_uid_t, to_zval_read_uid_t}, +#endif {0} }; void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx) diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c index e5dbc52fb1e5b..906e6b81007b5 100644 --- a/ext/sockets/sendrecvmsg.c +++ b/ext/sockets/sendrecvmsg.c @@ -121,8 +121,13 @@ static void init_ancillary_registry(void) #endif #ifdef SO_PASSCRED +#ifdef ANC_CREDS_UCRED PUT_ENTRY(sizeof(struct ucred), 0, 0, from_zval_write_ucred, to_zval_read_ucred, SOL_SOCKET, SCM_CREDENTIALS); +#else + PUT_ENTRY(sizeof(struct cmsgcred), 0, 0, from_zval_write_ucred, + to_zval_read_ucred, SOL_SOCKET, SCM_CREDS); +#endif #endif #ifdef SCM_RIGHTS @@ -436,7 +441,11 @@ void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS) REGISTER_LONG_CONSTANT("SCM_RIGHTS", SCM_RIGHTS, CONST_CS | CONST_PERSISTENT); #endif #ifdef SO_PASSCRED +#ifdef SCM_CREDENTIALS REGISTER_LONG_CONSTANT("SCM_CREDENTIALS", SCM_CREDENTIALS, CONST_CS | CONST_PERSISTENT); +#else + REGISTER_LONG_CONSTANT("SCM_CREDS", SCM_CREDS, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("SO_PASSCRED", SO_PASSCRED, CONST_CS | CONST_PERSISTENT); #endif From 80b02275bb2f0e7b3b448989910097cf897e7c93 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 11 Dec 2021 06:26:16 +0000 Subject: [PATCH 61/96] socket cmsg credential test fixes, "backporting" from the FreeBSD PR. --- ext/sockets/tests/socket_cmsg_credentials.phpt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/sockets/tests/socket_cmsg_credentials.phpt b/ext/sockets/tests/socket_cmsg_credentials.phpt index f2b56018d68c8..1a58b300c20ae 100644 --- a/ext/sockets/tests/socket_cmsg_credentials.phpt +++ b/ext/sockets/tests/socket_cmsg_credentials.phpt @@ -14,10 +14,6 @@ die('skip not for AIX'); if (!defined('SO_PASSCRED')) { die('skip SO_PASSCRED is not defined'); } ---CLEAN-- - +--CLEAN-- + Date: Wed, 22 Dec 2021 10:40:04 +0100 Subject: [PATCH 62/96] Fix the value param of SimpleXMLElement::addAttribute() Closes GH-7811 --- ext/simplexml/simplexml.stub.php | 2 +- ext/simplexml/simplexml_arginfo.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index a115c8b2defeb..4735573521587 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -44,7 +44,7 @@ public function __construct(string $data, int $options = 0, bool $dataIsURL = fa public function addChild(string $qualifiedName, ?string $value = null, ?string $namespace = null): ?SimpleXMLElement {} /** @tentative-return-type */ - public function addAttribute(string $qualifiedName, ?string $value = null, ?string $namespace = null): void {} + public function addAttribute(string $qualifiedName, string $value, ?string $namespace = null): void {} /** @tentative-return-type */ public function getName(): string {} diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 881051514c595..f6100eb243e31 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 46da4d24787a5f975eebeaab3872eb29273a9625 */ + * Stub hash: 06c88dc2fb5582a6d21c11aee6ac0a0538e70cbc */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_simplexml_load_file, 0, 1, SimpleXMLElement, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -67,9 +67,9 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_SimpleXMLElement_ ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, namespace, IS_STRING, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_addAttribute, 0, 1, IS_VOID, 0) +ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_addAttribute, 0, 2, IS_VOID, 0) ZEND_ARG_TYPE_INFO(0, qualifiedName, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, namespace, IS_STRING, 1, "null") ZEND_END_ARG_INFO() From c5f4ee50ab60ed4ff5ac74a0b11ccdd5e21cef96 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 22 Dec 2021 23:42:29 +0100 Subject: [PATCH 63/96] $context parameter of get_headers() is nullable Closes GH-7813. --- ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index acdb56af3ec1c..11f84c5b6e812 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -1433,7 +1433,7 @@ function rawurlencode(string $string): string {} function rawurldecode(string $string): string {} -/** @param resource $context */ +/** @param resource|null $context */ function get_headers(string $url, bool $associative = false, $context = null): array|false {} /* user_filters.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index bbd4a16899b3f..ac6e4c65aa1a9 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2da40c5fd9726f98ff96cf9fb5e0c41521e1e6ae */ + * Stub hash: ff0ec0005317a22c41e61e9c58f67e968d1243c4 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) From 096a01c9055c25093872f571d9de9a532321f2d9 Mon Sep 17 00:00:00 2001 From: Christophe Coevoet Date: Tue, 21 Dec 2021 12:58:31 +0100 Subject: [PATCH 64/96] [ci skip] Update the min curl version in the sync-constants.php script PHP 8.0 bumped the min curl version to 7.29.0 Closes GH-7805. --- ext/curl/sync-constants.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/curl/sync-constants.php b/ext/curl/sync-constants.php index 2db773d5f80a1..035dbcf6a237d 100755 --- a/ext/curl/sync-constants.php +++ b/ext/curl/sync-constants.php @@ -12,7 +12,7 @@ const SOURCE_FILE = __DIR__ . '/interface.c'; -const MIN_SUPPORTED_CURL_VERSION = '7.15.5'; +const MIN_SUPPORTED_CURL_VERSION = '7.29.0'; const IGNORED_CONSTANTS = [ 'CURLOPT_PROGRESSDATA' From 3f0bb673617f29fe7c022f2db86367ebf9c869e2 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 23 Dec 2021 14:21:47 +0000 Subject: [PATCH 65/96] Avoid void* arithmetic in sockets/multicast.c on NetBSD On NetBSD, ifconf.ifc_buf member, unlike most of platforms, is a void pointer. We also fix the cpuinfo declarations with empty parameter lists. Closes GH-7819. --- NEWS | 3 +++ Zend/zend_cpuinfo.c | 6 +++--- ext/sockets/multicast.c | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index ae1d224b6268d..2eafc4acad89e 100644 --- a/NEWS +++ b/NEWS @@ -24,6 +24,9 @@ PHP NEWS - PDO_PGSQL: . Fixed error message allocation of PDO PgSQL. (SATO Kentaro) +- Sockets: + . Avoid void* arithmetic in sockets/multicast.c on NetBSD. (David Carlier) + - Spl: . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr Bystry) diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 529ab529a3361..102b0f8c05d35 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -75,7 +75,7 @@ static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo #if defined(__i386__) || defined(__x86_64__) /* Function based on compiler-rt implementation. */ -static unsigned get_xcr0_eax() { +static unsigned get_xcr0_eax(void) { # if defined(__GNUC__) || defined(__clang__) // Check xgetbv; this uses a .byte sequence instead of the instruction // directly because older assemblers do not include support for xgetbv and @@ -90,7 +90,7 @@ static unsigned get_xcr0_eax() { # endif } -static zend_bool is_avx_supported() { +static zend_bool is_avx_supported(void) { if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_AVX)) { /* No support for AVX */ return 0; @@ -106,7 +106,7 @@ static zend_bool is_avx_supported() { return 1; } #else -static zend_bool is_avx_supported() { +static zend_bool is_avx_supported(void) { return 0; } #endif diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index 321efdc4039bc..25203c0fbccae 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -784,7 +784,7 @@ int php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, unsigned *i } for (p = if_conf.ifc_buf; - p < if_conf.ifc_buf + if_conf.ifc_len; + p < ((char *)if_conf.ifc_buf) + if_conf.ifc_len; p += entry_len) { /* p may be misaligned on macos. */ struct ifreq cur_req; From 0ed39ed809883043c2c339e00e6ff2d3cc34ba54 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 23 Dec 2021 00:14:44 +0100 Subject: [PATCH 66/96] Fix GH-7809: Cloning a faked SplFileInfo object may segfault While the `path` is not supposed to be `NULL` for normal operation, it is possible to create `SplFileInfo` objects where that is the case, and we must not follow the null pointer. Closes GH-7814. --- NEWS | 1 + ext/spl/spl_directory.c | 8 ++++++-- ext/spl/tests/gh7809.phpt | 12 ++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 ext/spl/tests/gh7809.phpt diff --git a/NEWS b/NEWS index 58f290ae8b50f..12ef79e2b82c6 100644 --- a/NEWS +++ b/NEWS @@ -53,6 +53,7 @@ PHP NEWS - Spl: . Fixed bug #75917 (SplFileObject::seek broken with CSV flags). (Aliaksandr Bystry) + . Fixed bug GH-7809 (Cloning a faked SplFileInfo object may segfault). (cmb) - Standard: . Fixed bug GH-7748 (gethostbyaddr outputs binary string). (cmb) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 116185846868d..0ba11f4800715 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -385,8 +385,12 @@ static zend_object *spl_filesystem_object_clone(zend_object *old_object) switch (source->type) { case SPL_FS_INFO: - intern->path = zend_string_copy(source->path); - intern->file_name = zend_string_copy(source->file_name); + if (source->path != NULL) { + intern->path = zend_string_copy(source->path); + } + if (source->file_name != NULL) { + intern->file_name = zend_string_copy(source->file_name); + } break; case SPL_FS_DIR: spl_filesystem_dir_open(intern, source->path); diff --git a/ext/spl/tests/gh7809.phpt b/ext/spl/tests/gh7809.phpt new file mode 100644 index 0000000000000..6406bef6c1438 --- /dev/null +++ b/ext/spl/tests/gh7809.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug GH-7809 (Cloning a faked SplFileInfo object may segfault) +--FILE-- + +--EXPECT-- From 2b81156f2a64ae99a4d431983e7c5a4ec7b817f7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 24 Dec 2021 13:10:22 +0300 Subject: [PATCH 67/96] Fix memory leak in SCCP Fixes oss-fuzz #42878 --- ext/opcache/Optimizer/sccp.c | 1 + ext/opcache/tests/opt/sccp_035.phpt | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 ext/opcache/tests/opt/sccp_035.phpt diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c index bdeb883aa562a..0818a20e0bf97 100644 --- a/ext/opcache/Optimizer/sccp.c +++ b/ext/opcache/Optimizer/sccp.c @@ -1547,6 +1547,7 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_PRE_DEC_OBJ) { SET_RESULT(result, &tmp2); + zval_ptr_dtor_nogc(&tmp1); } else { SET_RESULT(result, &tmp1); } diff --git a/ext/opcache/tests/opt/sccp_035.phpt b/ext/opcache/tests/opt/sccp_035.phpt new file mode 100644 index 0000000000000..86965b13b5f3d --- /dev/null +++ b/ext/opcache/tests/opt/sccp_035.phpt @@ -0,0 +1,17 @@ +--TEST-- +SCCP 035: memory leak +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.optimization_level=-1 +--FILE-- +$b = ~$b = $a=''; + $obj->$a--; +} +?> +DONE +--EXPECT-- +DONE From b4ba65dd9d615cc6bed93660cc6d0ab964e1e8ec Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 00:38:51 +0100 Subject: [PATCH 68/96] Fix chunk_split_variation*_32bit.phpt for Windows Both tests fail on Windows for slightly different reasons, what appears to be legit, and as such we fix the test expectations. Closes GH-7830. --- ext/standard/tests/strings/chunk_split_variation1_32bit.phpt | 2 +- ext/standard/tests/strings/chunk_split_variation2_32bit.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt index b2fd29ad88098..b4bef8add4103 100644 --- a/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation1_32bit.phpt @@ -17,4 +17,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 1 *** -Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d bytes) in %s on line %d +Fatal error: %rAllowed memory size of %d bytes exhausted%s\(tried to allocate %d bytes\)|Possible integer overflow in memory allocation \(4294901777 \+ 2097152\)%r in %s on line %d diff --git a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt index 0f777fbd38605..c83a37f00edb4 100644 --- a/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt +++ b/ext/standard/tests/strings/chunk_split_variation2_32bit.phpt @@ -16,4 +16,4 @@ var_dump(chunk_split($a,$b,$c)); --EXPECTF-- *** Testing chunk_split() : unexpected large 'end' string argument variation 2 *** -Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + 65556) in %s on line %d +Fatal error: Possible integer overflow in memory allocation (65537 * 65537 + %r65556|65560%r) in %s on line %d From fd3fc5c193d056923340d74d4f5be407c089ba94 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 00:05:03 +0100 Subject: [PATCH 69/96] Fix GH-7826: Inconsistent argument name in hash_hmac_file and hash_file Like `hash_file()`, `hash_hmac_file()` expects a filename, and not some string data. Fixing this now, constitutes a (hopefully small) BC break though. Closes GH-7828. --- NEWS | 2 ++ ext/hash/hash.stub.php | 2 +- ext/hash/hash_arginfo.h | 4 ++-- ext/hash/tests/hash_hmac_file_error.phpt | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 2eafc4acad89e..30f8b64959f5a 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ PHP NEWS - Hash: . Fixed bug GH-7759 (Incorrect return types for hash() and hash_hmac()). (cmb) + . Fixed bug GH-7826 (Inconsistent argument name in hash_hmac_file and + hash_file). (cmb) - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second diff --git a/ext/hash/hash.stub.php b/ext/hash/hash.stub.php index 250fb68ee4e9f..0a9ac41100b9d 100644 --- a/ext/hash/hash.stub.php +++ b/ext/hash/hash.stub.php @@ -8,7 +8,7 @@ function hash_file(string $algo, string $filename, bool $binary = false): string function hash_hmac(string $algo, string $data, string $key, bool $binary = false): string {} -function hash_hmac_file(string $algo, string $data, string $key, bool $binary = false): string|false {} +function hash_hmac_file(string $algo, string $filename, string $key, bool $binary = false): string|false {} function hash_init(string $algo, int $flags = 0, string $key = ""): HashContext {} diff --git a/ext/hash/hash_arginfo.h b/ext/hash/hash_arginfo.h index 5aef2c11d1d61..ade717d4002f4 100644 --- a/ext/hash/hash_arginfo.h +++ b/ext/hash/hash_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f73c6fa1a4ac1ca93f87775bbe69fbdb2deb5746 */ + * Stub hash: ae4f5ceba77eee7062cbd2fadb112aac33d198ce */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hash, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) @@ -22,7 +22,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_hash_hmac_file, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, algo, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, binary, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() diff --git a/ext/hash/tests/hash_hmac_file_error.phpt b/ext/hash/tests/hash_hmac_file_error.phpt index 7cbc347691202..3a4d85ee7e35b 100644 --- a/ext/hash/tests/hash_hmac_file_error.phpt +++ b/ext/hash/tests/hash_hmac_file_error.phpt @@ -43,4 +43,4 @@ hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algo hash_hmac_file(): Argument #1 ($algo) must be a valid cryptographic hashing algorithm -- Testing hash_hmac_file() function with bad path -- -hash_hmac_file(): Argument #2 ($data) must not contain any null bytes +hash_hmac_file(): Argument #2 ($filename) must not contain any null bytes From e76ddbd2f6b42e2824da4478392f98a300ab18ab Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 25 Dec 2021 23:04:39 +0100 Subject: [PATCH 70/96] Prevent strict interpretation of tentative definition This header declaration is never supposed to be interpreted as definition; otherwise, the handlers are not properly initialized, what happens, for instance, with ASan instrumented MSVC builds. Closes GH-7827. --- ext/com_dotnet/php_com_dotnet_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index e80bf6e3126eb..eec92fcb86a17 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -72,7 +72,7 @@ zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_entry, * zend_object* php_com_object_new(zend_class_entry *ce); zend_object* php_com_object_clone(zend_object *object); void php_com_object_free_storage(zend_object *object); -zend_object_handlers php_com_object_handlers; +extern zend_object_handlers php_com_object_handlers; void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable); /* com_saproxy.c */ From 5005445994ff03e01524cff345e9c0d60027f662 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Dec 2021 13:48:26 +0100 Subject: [PATCH 71/96] Mark curl tests using http2.golang.org as XFAIL http2.golang.org/serverpush has been retired[1], so we need to come up with an alternative. Until then, we mark the relevant tests as XFAIL (although bug77535.phpt passes, what might be an indication that the test needs further revision). To avoid waiting for the timeout, we also unconditionally skip these tests for now. [1] Closes GH-7829. --- ext/curl/tests/bug76675.phpt | 3 +++ ext/curl/tests/bug77535.phpt | 3 +++ 2 files changed, 6 insertions(+) diff --git a/ext/curl/tests/bug76675.phpt b/ext/curl/tests/bug76675.phpt index 5d36abfdd671b..c52874a6ed37d 100644 --- a/ext/curl/tests/bug76675.phpt +++ b/ext/curl/tests/bug76675.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #76675 (Segfault with H2 server push write/writeheader handlers) +--XFAIL-- +http2.golang.org/serverpush is gone --SKIPIF-- --FILE-- --FILE-- Date: Sun, 26 Dec 2021 16:49:32 +0100 Subject: [PATCH 72/96] Fix bug40228*.phpt conflict Both tests use the same directory structure; we avoid that by extracting to separate subdirectories. Closes GH-7831. --- ext/zip/tests/bug40228-mb.phpt | 5 +++-- ext/zip/tests/bug40228.phpt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/zip/tests/bug40228-mb.phpt b/ext/zip/tests/bug40228-mb.phpt index fddfb65f29639..39715a615a02a 100644 --- a/ext/zip/tests/bug40228-mb.phpt +++ b/ext/zip/tests/bug40228-mb.phpt @@ -4,8 +4,8 @@ Bug #40228 (extractTo does not create recursive empty path) --FILE-- open($arc_name, ZIPARCHIVE::CREATE); $zip->extractTo($dest); @@ -13,6 +13,7 @@ if (is_dir($dest . '/test/empty')) { echo "Ok\n"; rmdir($dest . '/test/empty'); rmdir($dest . '/test'); + rmdir($dest); } else { echo "Failed.\n"; } diff --git a/ext/zip/tests/bug40228.phpt b/ext/zip/tests/bug40228.phpt index 49e202c576baf..f9cd20f2439d1 100644 --- a/ext/zip/tests/bug40228.phpt +++ b/ext/zip/tests/bug40228.phpt @@ -4,8 +4,8 @@ Bug #40228 (extractTo does not create recursive empty path) --FILE-- open($arc_name, ZIPARCHIVE::CREATE); $zip->extractTo($dest); @@ -13,6 +13,7 @@ if (is_dir($dest . '/test/empty')) { echo "Ok\n"; rmdir($dest . '/test/empty'); rmdir($dest . '/test'); + rmdir($dest); } else { echo "Failed.\n"; } From f82593d597f5d23fadca1ba5e7d076392d11faaf Mon Sep 17 00:00:00 2001 From: David Warner Date: Thu, 23 Dec 2021 22:52:50 +1100 Subject: [PATCH 73/96] Fix GH-7815: php_uname doesn't recognise latest Windows versions We check `dwBuildNumber` to determine newer Windows versions. Closes GH-7816. --- NEWS | 2 ++ ext/standard/info.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index b33abd8be9b3a..ecf24e5d08005 100644 --- a/NEWS +++ b/NEWS @@ -59,6 +59,8 @@ PHP NEWS - Standard: . Fixed bug GH-7748 (gethostbyaddr outputs binary string). (cmb) + . Fixed bug GH-7815 (php_uname doesn't recognise latest Windows versions). + (David Warner) 02 Dec 2021, PHP 8.1.1 diff --git a/ext/standard/info.c b/ext/standard/info.c index 395110d25f218..651bf3ae3f6d7 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -268,11 +268,34 @@ char* php_get_windows_name() if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) { if (osvi.dwMajorVersion == 10) { - if( osvi.dwMinorVersion == 0 ) { - if( osvi.wProductType == VER_NT_WORKSTATION ) { - major = "Windows 10"; + if (osvi.dwMinorVersion == 0) { + if (osvi.wProductType == VER_NT_WORKSTATION) { + if (osvi.dwBuildNumber >= 22000) { + major = "Windows 11"; + } else { + major = "Windows 10"; + } } else { - major = "Windows Server 2016"; + if (osvi.dwBuildNumber >= 20348) { + major = "Windows Server 2022"; + } else if (osvi.dwBuildNumber >= 19042) { + major = "Windows Server, version 20H2"; + } else if (osvi.dwBuildNumber >= 19041) { + major = "Windows Server, version 2004"; + } else if (osvi.dwBuildNumber >= 18363) { + major = "Windows Server, version 1909"; + } else if (osvi.dwBuildNumber >= 18362) { + major = "Windows Server, version 1903"; + } else if (osvi.dwBuildNumber >= 17763) { + // could also be Windows Server, version 1809, but there's no easy way to tell + major = "Windows Server 2019"; + } else if (osvi.dwBuildNumber >= 17134) { + major = "Windows Server, version 1803"; + } else if (osvi.dwBuildNumber >= 16299) { + major = "Windows Server, version 1709"; + } else { + major = "Windows Server 2016"; + } } } } From 76e2a8380e5e030412e9d565955d011972af8418 Mon Sep 17 00:00:00 2001 From: Florian Sowade Date: Thu, 18 Nov 2021 16:16:37 +0100 Subject: [PATCH 74/96] Fix zend_observer_fcall_end_all() accessing dangling pointers This may happen, when the execute_data was allocated on the stack. We ensure that the runtime cache pointer is not NULL before dereferencing it. This is a partial fix for bug 81430. Closes GH-7665. --- NEWS | 2 ++ Zend/zend_observer.c | 1 + ext/zend_test/tests/observer_bug81430_1.phpt | 27 ++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 ext/zend_test/tests/observer_bug81430_1.phpt diff --git a/NEWS b/NEWS index 30f8b64959f5a..cbbd41ab5e1eb 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) + . Fixed zend_observer_fcall_end_all() accessing dangling pointers. (Florian + Sowade) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index b970acd85c8e5..08c09e8ff1773 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -229,6 +229,7 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( zend_execute_data *ex = execute_data->prev_execute_data; while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) + || !&RUN_TIME_CACHE(&ex->func->op_array) || !ZEND_OBSERVER_DATA(&ex->func->op_array) || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { ex = ex->prev_execute_data; diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt new file mode 100644 index 0000000000000..830112b1b5370 --- /dev/null +++ b/ext/zend_test/tests/observer_bug81430_1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #81430 (Attribute instantiation frame has no run time cache) +--INI-- +memory_limit=20M +zend_test.observer.enabled=1 +zend_test.observer.observe_all=1 +--FILE-- +getAttributes(A::class)[0], 'newInstance']); +?> +--EXPECTF-- + + + + + + From ee610947ce03a5d83447f144886b4d5278e1b47b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 27 Dec 2021 21:08:51 +0100 Subject: [PATCH 75/96] Revert "Fix zend_observer_fcall_end_all() accessing dangling pointers" This reverts commit 76e2a8380e5e030412e9d565955d011972af8418. Cf. . --- NEWS | 2 -- Zend/zend_observer.c | 1 - ext/zend_test/tests/observer_bug81430_1.phpt | 27 -------------------- 3 files changed, 30 deletions(-) delete mode 100644 ext/zend_test/tests/observer_bug81430_1.phpt diff --git a/NEWS b/NEWS index cbbd41ab5e1eb..30f8b64959f5a 100644 --- a/NEWS +++ b/NEWS @@ -6,8 +6,6 @@ PHP NEWS . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) . Fixed bug #81585 (cached_chunks are not counted to real_size on shutdown). (cmb) - . Fixed zend_observer_fcall_end_all() accessing dangling pointers. (Florian - Sowade) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index 08c09e8ff1773..b970acd85c8e5 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -229,7 +229,6 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end( zend_execute_data *ex = execute_data->prev_execute_data; while (ex && (!ex->func || ex->func->type == ZEND_INTERNAL_FUNCTION || !ZEND_OBSERVABLE_FN(ex->func->common.fn_flags) - || !&RUN_TIME_CACHE(&ex->func->op_array) || !ZEND_OBSERVER_DATA(&ex->func->op_array) || ZEND_OBSERVER_DATA(&ex->func->op_array) == ZEND_OBSERVER_NOT_OBSERVED)) { ex = ex->prev_execute_data; diff --git a/ext/zend_test/tests/observer_bug81430_1.phpt b/ext/zend_test/tests/observer_bug81430_1.phpt deleted file mode 100644 index 830112b1b5370..0000000000000 --- a/ext/zend_test/tests/observer_bug81430_1.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Bug #81430 (Attribute instantiation frame has no run time cache) ---INI-- -memory_limit=20M -zend_test.observer.enabled=1 -zend_test.observer.observe_all=1 ---FILE-- -getAttributes(A::class)[0], 'newInstance']); -?> ---EXPECTF-- - - - - - - From 87d9e02f01cf835deada04e4639b073144c14ee9 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 27 Dec 2021 13:44:53 +0100 Subject: [PATCH 76/96] Don't truncate subsecond precision in run-tests.php JUNIT output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When run-tests.php has been typed[1], the type of `$time` has been chosen to be `int`. This, however, leads to truncation, and the somewhat relevant subsecond precision is lost. We fix that by changing the type to `float`, although `int|string` would be more appropriate, but requires PHP ≥ 7.4.0. Another option would be to move the `number_format()` formatting into `junit_mark_test_as()`. [1] Closes GH-7836. --- run-tests.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/run-tests.php b/run-tests.php index 333b6058fbed1..709c657c2f0fe 100755 --- a/run-tests.php +++ b/run-tests.php @@ -3478,7 +3478,7 @@ function junit_mark_test_as( $type, string $file_name, string $test_name, - ?int $time = null, + ?float $time = null, string $message = '', string $details = '' ): void { @@ -3533,7 +3533,7 @@ function junit_mark_test_as( $JUNIT['files'][$file_name]['xml'] .= "\n"; } -function junit_suite_record(string $suite, string $param, int $value = 1): void +function junit_suite_record(string $suite, string $param, float $value = 1): void { global $JUNIT; @@ -3541,7 +3541,7 @@ function junit_suite_record(string $suite, string $param, int $value = 1): void $JUNIT['suites'][$suite][$param] += $value; } -function junit_get_timer(string $file_name): int +function junit_get_timer(string $file_name): float { global $JUNIT; if (!junit_enabled()) { From de358f856fea56ad2b7ff79f3f7daa91ee99b32a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 09:57:03 +0300 Subject: [PATCH 77/96] Fix reference contig inference Fixes oss-fuzz #43032 --- ext/opcache/Optimizer/zend_inference.c | 25 +++++++++++++++++++++--- ext/opcache/tests/jit/fetch_obj_009.phpt | 21 ++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 ext/opcache/tests/jit/fetch_obj_009.phpt diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index feb469303c497..46f0f1e076a9c 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -2191,6 +2191,25 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, zend_property_in return MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_RC1 | MAY_BE_RCN; } +static zend_bool result_may_be_separated(zend_ssa *ssa, zend_ssa_op *ssa_op) +{ + int tmp_var = ssa_op->result_def; + + if (ssa->vars[tmp_var].use_chain >= 0 + && !ssa->vars[tmp_var].phi_use_chain) { + zend_ssa_op *use_op = &ssa->ops[ssa->vars[tmp_var].use_chain]; + + /* TODO: analize instructions between ssa_op and use_op */ + if (use_op == ssa_op + 1) { + if ((use_op->op1_use == tmp_var && use_op->op1_use_chain < 0) + || (use_op->op2_use == tmp_var && use_op->op2_use_chain < 0)) { + return 0; + } + } + } + return 1; +} + static zend_always_inline int _zend_update_type_info( const zend_op_array *op_array, zend_ssa *ssa, @@ -3307,11 +3326,11 @@ static zend_always_inline int _zend_update_type_info( if (prop_info) { /* FETCH_OBJ_R/IS for plain property increments reference counter, so it can't be 1 */ - if (ce && !ce->create_object) { + if (ce && !ce->create_object && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } else { - if (ce && !ce->create_object && !ce->__get) { + if (ce && !ce->create_object && !ce->__get && !result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } } @@ -3336,7 +3355,7 @@ static zend_always_inline int _zend_update_type_info( zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce); if (opline->result_type != IS_TMP_VAR) { tmp |= MAY_BE_REF | MAY_BE_INDIRECT; - } else { + } else if (!result_may_be_separated(ssa, ssa_op)) { tmp &= ~MAY_BE_RC1; } UPDATE_SSA_TYPE(tmp, ssa_op->result_def); diff --git a/ext/opcache/tests/jit/fetch_obj_009.phpt b/ext/opcache/tests/jit/fetch_obj_009.phpt new file mode 100644 index 0000000000000..92d67de08abbf --- /dev/null +++ b/ext/opcache/tests/jit/fetch_obj_009.phpt @@ -0,0 +1,21 @@ +--TEST-- +JIT: FETCH_OBJ 009 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- +x[0] = null; + $obj->x > $obj->x[0] = null; + } +} +test(); +?> +DONE +--EXPECT-- +DONE From cb3d85874543a8e5c092353402c13776c775a912 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 27 Dec 2021 10:05:02 +0000 Subject: [PATCH 78/96] Fix buffer allocations in zlog_stream_set_msg_suffix() If that code was used, there would be a UAF scenario. Closes GH-7835. --- sapi/fpm/fpm/zlog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/fpm/fpm/zlog.c b/sapi/fpm/fpm/zlog.c index 4808447f5c924..0938f08e89de4 100644 --- a/sapi/fpm/fpm/zlog.c +++ b/sapi/fpm/fpm/zlog.c @@ -637,10 +637,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (suffix != NULL) { stream->msg_suffix_len = strlen(suffix); len = stream->msg_suffix_len + 1; - stream->msg_suffix = malloc(len); if (stream->msg_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_suffix = malloc(len); if (stream->msg_suffix == NULL) { return ZLOG_FALSE; } @@ -650,10 +650,10 @@ zlog_bool zlog_stream_set_msg_suffix( if (final_suffix != NULL) { stream->msg_final_suffix_len = strlen(final_suffix); len = stream->msg_final_suffix_len + 1; - stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix != NULL) { free(stream->msg_suffix); } + stream->msg_final_suffix = malloc(len); if (stream->msg_final_suffix == NULL) { return ZLOG_FALSE; } From fd879e6fe47c5d83e9f2e9fd2f72e6b1b548a02a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 16:51:03 +0300 Subject: [PATCH 79/96] JIT: Fix array clobbering by user error handler Gixes oss-fuzz #43055 --- ext/opcache/jit/zend_jit_helpers.c | 64 ++++++++++++++++++++++ ext/opcache/tests/jit/fetch_dim_r_010.phpt | 19 +++++++ 2 files changed, 83 insertions(+) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_010.phpt diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 4595afdc17873..2eb3bb3cc1880 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -456,6 +456,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -469,7 +471,31 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_r_helper(zend_array *ht, zval *dim, offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); @@ -531,6 +557,8 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim zend_ulong hval; zend_string *offset_key; zval *retval; + zend_execute_data *execute_data; + const zend_op *opline; if (Z_TYPE_P(dim) == IS_REFERENCE) { dim = Z_REFVAL_P(dim); @@ -544,7 +572,31 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_is_helper(zend_array *ht, zval *dim offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + execute_data = EG(current_execute_data); + opline = EX(opline); zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } else { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + return; + } + if (EG(exception)) { + if (opline->result_type & (IS_VAR | IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + return; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); @@ -616,7 +668,19 @@ static int ZEND_FASTCALL zend_jit_fetch_dim_isset_helper(zend_array *ht, zval *d offset_key = Z_STR_P(dim); goto str_index; case IS_UNDEF: + /* The array may be destroyed while throwing the notice. + * Temporarily increase the refcount to detect this situation. */ + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + return 0; + } + if (EG(exception)) { + return 0; + } /* break missing intentionally */ case IS_NULL: offset_key = ZSTR_EMPTY_ALLOC(); diff --git a/ext/opcache/tests/jit/fetch_dim_r_010.phpt b/ext/opcache/tests/jit/fetch_dim_r_010.phpt new file mode 100644 index 0000000000000..201d0b40f5bd3 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_010.phpt @@ -0,0 +1,19 @@ +--TEST-- +JIT FETCH_DIM_R: 010 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 206bcff50d9a5ec1d26ab480f93c0ef539644408 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 28 Dec 2021 16:56:23 +0300 Subject: [PATCH 80/96] iSeparate tests --- ext/opcache/tests/jit/fetch_dim_r_010.phpt | 1 - ext/opcache/tests/jit/fetch_dim_r_011.phpt | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/opcache/tests/jit/fetch_dim_r_011.phpt diff --git a/ext/opcache/tests/jit/fetch_dim_r_010.phpt b/ext/opcache/tests/jit/fetch_dim_r_010.phpt index 201d0b40f5bd3..677f4a411b6aa 100644 --- a/ext/opcache/tests/jit/fetch_dim_r_010.phpt +++ b/ext/opcache/tests/jit/fetch_dim_r_010.phpt @@ -12,7 +12,6 @@ set_error_handler(function() { }); $a = [$y]; ($a[$b]); -($a[17604692317316877817]); ?> DONE --EXPECT-- diff --git a/ext/opcache/tests/jit/fetch_dim_r_011.phpt b/ext/opcache/tests/jit/fetch_dim_r_011.phpt new file mode 100644 index 0000000000000..3ef3733f19c00 --- /dev/null +++ b/ext/opcache/tests/jit/fetch_dim_r_011.phpt @@ -0,0 +1,18 @@ +--TEST-- +JIT FETCH_DIM_R: 011 +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +opcache.jit_buffer_size=1M +--FILE-- + +DONE +--EXPECT-- +DONE From 24be11f632496796514b90d66219a535a3152305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 28 Dec 2021 14:13:25 +0100 Subject: [PATCH 81/96] Remove bogus type of $object param in SplObjectStorage::offsetSet() This parameter definitely only accepts objects, so we shouldn't explicitly mark it as mixed. Looks like I accidentally added this type when adding the tentative return type. Closes GH-7840 --- ext/spl/spl_observer.stub.php | 2 +- ext/spl/spl_observer_arginfo.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index e5ea360354f4d..ed327aa7aad6b 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -90,7 +90,7 @@ public function offsetGet($object): mixed {} * @implementation-alias SplObjectStorage::attach * @no-verify Cannot specify arg type because ArrayAccess does not */ - public function offsetSet(mixed $object, mixed $info = null): void {} + public function offsetSet($object, mixed $info = null): void {} /** * @param object $object diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 5e9044a088f1e..94991119cb6f1 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a3c87f5b7edd257e25d6651628dd9896e14f5715 */ + * Stub hash: 63dde3294f600164805befd79b1f670fbfb23571 */ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObserver_update, 0, 1, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, subject, SplSubject, 0) @@ -75,7 +75,7 @@ ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_SplObjectStorage_offsetSet, 0, 1, IS_VOID, 0) - ZEND_ARG_TYPE_INFO(0, object, IS_MIXED, 0) + ZEND_ARG_INFO(0, object) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, info, IS_MIXED, 0, "null") ZEND_END_ARG_INFO() From 8869bbe0e9a37293e3f790b5fb891e765000d7d9 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 30 Dec 2021 14:15:29 +0000 Subject: [PATCH 82/96] Fix bug GH-7746 (mysqli_sql_exception->sqlstate is inaccessible) Closes GH-7747 --- NEWS | 1 + ext/mysqli/mysqli.stub.php | 2 ++ ext/mysqli/mysqli_arginfo.h | 7 ++++++- ext/mysqli/mysqli_exception.c | 14 ++++++++++++++ ext/mysqli/tests/gh7746.phpt | 25 +++++++++++++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 ext/mysqli/tests/gh7746.phpt diff --git a/NEWS b/NEWS index ecf24e5d08005..2ba941999f0e6 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ PHP NEWS . Fixed bug #81658 (MYSQL_OPT_LOAD_DATA_LOCAL_DIR not available in MariaDB). (devnexen) . Introduced MYSQLI_IS_MARIADB. (devnexen) + . Fixed bug GH-7746 (mysqli_sql_exception->getSqlState()). (Kamil Tekiela) - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index e0c46a5427bcb..be0bbbc919b25 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -613,6 +613,8 @@ public function next(): bool {} final class mysqli_sql_exception extends RuntimeException { protected string $sqlstate = "00000"; + + public function getSqlState(): string {} } /** @refcount 1 */ diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 4cd285e347f47..a0168a51c7a98 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: e9f4dd04e7d01864c38033bcaf5e03b63e191deb */ + * Stub hash: 78662c05cd463735a8a4101c0357fd0d2698d48e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) @@ -720,6 +720,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_mysqli_warning_next arginfo_mysqli_thread_safe +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_mysqli_sql_exception_getSqlState, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_FUNCTION(mysqli_affected_rows); ZEND_FUNCTION(mysqli_autocommit); @@ -842,6 +845,7 @@ ZEND_METHOD(mysqli_result, getIterator); ZEND_METHOD(mysqli_stmt, __construct); ZEND_METHOD(mysqli_warning, __construct); ZEND_METHOD(mysqli_warning, next); +ZEND_METHOD(mysqli_sql_exception, getSqlState); static const zend_function_entry ext_functions[] = { @@ -1083,6 +1087,7 @@ static const zend_function_entry class_mysqli_warning_methods[] = { static const zend_function_entry class_mysqli_sql_exception_methods[] = { + ZEND_ME(mysqli_sql_exception, getSqlState, arginfo_class_mysqli_sql_exception_getSqlState, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/ext/mysqli/mysqli_exception.c b/ext/mysqli/mysqli_exception.c index 3bc80807a7e98..3d15881863e24 100644 --- a/ext/mysqli/mysqli_exception.c +++ b/ext/mysqli/mysqli_exception.c @@ -63,3 +63,17 @@ void php_mysqli_throw_sql_exception(char *sqlstate, int errorno, char *format, . zend_throw_exception_object(&sql_ex); } + +PHP_METHOD(mysqli_sql_exception, getSqlState) +{ + zval *prop; + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + prop = zend_read_property(mysqli_exception_class_entry, Z_OBJ_P(ZEND_THIS), "sqlstate", sizeof("sqlstate")-1, 1, &rv); + ZVAL_DEREF(prop); + zend_string *str = zval_get_string(prop); + + RETURN_STR(str); +} diff --git a/ext/mysqli/tests/gh7746.phpt b/ext/mysqli/tests/gh7746.phpt new file mode 100644 index 0000000000000..18fdb03451377 --- /dev/null +++ b/ext/mysqli/tests/gh7746.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #GH-7746 mysqli_sql_exception->sqlstate is inaccessible +--EXTENSIONS-- +mysqli +--SKIPIF-- + +--FILE-- +query("stuff"); +} catch (mysqli_sql_exception $exception) { + var_dump($exception->getSqlState()); +} + +?> +--EXPECT-- +string(5) "42000" From b63e4cf727ec596373c21079c5e2f37eec5dd59d Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 30 Dec 2021 16:55:21 +0100 Subject: [PATCH 83/96] Handle holes in zend_get_opcode_id() Some opcodes may currently not be allocated. --- Zend/zend_vm_gen.php | 3 ++- Zend/zend_vm_opcodes.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 343447a8d8983..45d559f26c7c4 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2688,7 +2688,8 @@ function gen_vm($def, $skel) { fputs($f, "ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) {\n"); fputs($f, "\tzend_uchar opcode;\n"); fputs($f, "\tfor (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) {\n"); - fputs($f, "\t\tif (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) {\n"); + fputs($f, "\t\tconst char *opcode_name = zend_vm_opcodes_names[opcode];\n"); + fputs($f, "\t\tif (opcode_name && strncmp(opcode_name, name, length) == 0) {\n"); fputs($f, "\t\t\treturn opcode;\n"); fputs($f, "\t\t}\n"); fputs($f, "\t}\n"); diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 7f88f9e84b690..085c473d59578 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -449,7 +449,8 @@ ZEND_API uint32_t ZEND_FASTCALL zend_get_opcode_flags(zend_uchar opcode) { ZEND_API zend_uchar zend_get_opcode_id(const char *name, size_t length) { zend_uchar opcode; for (opcode = 0; opcode < (sizeof(zend_vm_opcodes_names) / sizeof(zend_vm_opcodes_names[0])) - 1; opcode++) { - if (strncmp(zend_vm_opcodes_names[opcode], name, length) == 0) { + const char *opcode_name = zend_vm_opcodes_names[opcode]; + if (opcode_name && strncmp(opcode_name, name, length) == 0) { return opcode; } } From b3903515bfe962529f1e9fd9aa4d3b761def868f Mon Sep 17 00:00:00 2001 From: NathanFreeman <1056159381@qq.com> Date: Wed, 29 Dec 2021 16:11:14 +0100 Subject: [PATCH 84/96] Fix bug where large bigints may be truncated Unless stringified results are requested, we need to parse large bigints as unsigned, to avoid wrap-around behavior. Co-authored-by: Christoph M. Becker Closes GH-7837. --- NEWS | 3 +++ ext/mysqli/tests/gh7837.phpt | 42 ++++++++++++++++++++++++++++++ ext/mysqlnd/mysqlnd_wireprotocol.c | 4 +-- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 ext/mysqli/tests/gh7837.phpt diff --git a/NEWS b/NEWS index 30f8b64959f5a..7f2292bc4a732 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,9 @@ PHP NEWS . Fixed bug GH-7826 (Inconsistent argument name in hash_hmac_file and hash_file). (cmb) +- MySQLnd: + . Fixed bug where large bigints may be truncated. (Nathan Freeman, cmb) + - OCI8: . Fixed bug GH-7765 (php_oci_cleanup_global_handles segfaults at second call). (cmb) diff --git a/ext/mysqli/tests/gh7837.phpt b/ext/mysqli/tests/gh7837.phpt new file mode 100644 index 0000000000000..dc361c2bc1306 --- /dev/null +++ b/ext/mysqli/tests/gh7837.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug GH-7837 (large bigints may be truncated) +--SKIPIF-- + +--FILE-- +options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); +$mysql->query("DROP TABLE IF EXISTS test"); +$mysql->query("CREATE TABLE test (`ubigint` bigint unsigned NOT NULL) ENGINE=InnoDB"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (18446744073709551615)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (9223372036854775808)"); +$mysql->query("INSERT INTO test (`ubigint`) VALUES (1)"); +$result = $mysql->query("SELECT ubigint FROM test"); +var_dump($result->fetch_all()); +?> +--EXPECT-- +array(3) { + [0]=> + array(1) { + [0]=> + string(20) "18446744073709551615" + } + [1]=> + array(1) { + [0]=> + string(19) "9223372036854775808" + } + [2]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 63503f5c9849c..b83de494c2f7d 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -1634,9 +1634,9 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_ROW_BUFFER * row_buffer, zval * } else { uint64_t v = #ifndef PHP_WIN32 - (uint64_t) atoll((char *) p); + strtoull((char *) p, NULL, 10); #else - (uint64_t) _atoi64((char *) p); + _strtoui64((char *) p, NULL, 10); #endif zend_bool uns = fields_metadata[i].flags & UNSIGNED_FLAG? TRUE:FALSE; /* We have to make it ASCIIZ temporarily */ From 49512b6b36f18295277da33967b143071cb60012 Mon Sep 17 00:00:00 2001 From: Kamil Tekiela Date: Thu, 30 Dec 2021 19:25:32 +0000 Subject: [PATCH 85/96] Fix formatting in the new mysqli test --- ext/mysqli/tests/gh7837.phpt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ext/mysqli/tests/gh7837.phpt b/ext/mysqli/tests/gh7837.phpt index dc361c2bc1306..40f8fabeee6c0 100644 --- a/ext/mysqli/tests/gh7837.phpt +++ b/ext/mysqli/tests/gh7837.phpt @@ -2,15 +2,15 @@ Bug GH-7837 (large bigints may be truncated) --SKIPIF-- --FILE-- options(MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true); @@ -22,6 +22,10 @@ $mysql->query("INSERT INTO test (`ubigint`) VALUES (1)"); $result = $mysql->query("SELECT ubigint FROM test"); var_dump($result->fetch_all()); ?> +--CLEAN-- + --EXPECT-- array(3) { [0]=> From d963b3f015ad606050a45c9ac3c97c7726b0ad81 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Fri, 31 Dec 2021 00:22:29 +0100 Subject: [PATCH 86/96] mysqli_next_result_no_repeat_error.phpt must not use --EXTENSIONS-- This is only properly supported as of PHP 8.1.0[1], and may cause spurious test failures for older versions[2]. [1] [2] --- ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt b/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt index 22fb70979650d..7241ef7dd0cc7 100644 --- a/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt +++ b/ext/mysqli/tests/mysqli_next_result_no_repeat_error.phpt @@ -1,9 +1,8 @@ --TEST-- next_result reports errors from previous calls ---EXTENSIONS-- -mysqli --SKIPIF-- --FILE-- From 96a5026bfd43415676a730b351d38ed64b9d711d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 28 Dec 2021 14:06:12 +0100 Subject: [PATCH 87/96] Redefine PDOException::$code with correct type Closes GH-7839 --- ext/pdo/pdo.stub.php | 2 ++ ext/pdo/pdo_arginfo.h | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/pdo/pdo.stub.php b/ext/pdo/pdo.stub.php index 39a508bafcb15..ebe81b7a51ad8 100644 --- a/ext/pdo/pdo.stub.php +++ b/ext/pdo/pdo.stub.php @@ -4,6 +4,8 @@ class PDOException extends RuntimeException { + /** @var int|string */ + protected $code = 0; public ?array $errorInfo = null; } diff --git a/ext/pdo/pdo_arginfo.h b/ext/pdo/pdo_arginfo.h index d4c74eef624f8..72eda0c3ae99a 100644 --- a/ext/pdo/pdo_arginfo.h +++ b/ext/pdo/pdo_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 52ee252fdfc80d4d076f1c49842e333c27ed5102 */ + * Stub hash: 8d975a20d009e827f8d72ac19b94b55870b6bf9c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pdo_drivers, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -25,6 +25,12 @@ static zend_class_entry *register_class_PDOException(zend_class_entry *class_ent INIT_CLASS_ENTRY(ce, "PDOException", class_PDOException_methods); class_entry = zend_register_internal_class_ex(&ce, class_entry_RuntimeException); + zval property_code_default_value; + ZVAL_LONG(&property_code_default_value, 0); + zend_string *property_code_name = zend_string_init("code", sizeof("code") - 1, 1); + zend_declare_property_ex(class_entry, property_code_name, &property_code_default_value, ZEND_ACC_PROTECTED, NULL); + zend_string_release(property_code_name); + zval property_errorInfo_default_value; ZVAL_NULL(&property_errorInfo_default_value); zend_string *property_errorInfo_name = zend_string_init("errorInfo", sizeof("errorInfo") - 1, 1); From f70ca0acd4b3f1c7b8fdcabd13de354530091f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Tue, 28 Dec 2021 09:52:27 +0100 Subject: [PATCH 88/96] Mark mysqli_driver properties readonly --- ext/mysqli/mysqli.stub.php | 3 +++ ext/mysqli/mysqli_arginfo.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index be0bbbc919b25..40f82e42e7036 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -4,10 +4,13 @@ final class mysqli_driver { + /** @readonly */ public string $client_info; + /** @readonly */ public int $client_version; + /** @readonly */ public int $driver_version; public bool $reconnect = false; diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index a0168a51c7a98..c177963d1548f 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 78662c05cd463735a8a4101c0357fd0d2698d48e */ + * Stub hash: baf4cb58df96edeb4fc14e4703fe9363cf5ed784 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql, mysqli, 0) From 70b02d75f2abe3a292d49c4a4e9e4f850c2fee68 Mon Sep 17 00:00:00 2001 From: Jeremie Courreges-Anglas Date: Mon, 3 Jan 2022 11:57:29 +0100 Subject: [PATCH 89/96] riscv64 support for fibers We add riscv64 assembly files from Boost, needed for fibers support, and hook up riscv64 fibers support during configure. Closes GH-7879. --- NEWS | 1 + Zend/asm/jump_riscv64_sysv_elf_gas.S | 150 +++++++++++++++++++++++++++ Zend/asm/make_riscv64_sysv_elf_gas.S | 91 ++++++++++++++++ configure.ac | 2 + 4 files changed, 244 insertions(+) create mode 100644 Zend/asm/jump_riscv64_sysv_elf_gas.S create mode 100644 Zend/asm/make_riscv64_sysv_elf_gas.S diff --git a/NEWS b/NEWS index f28db7e2f40d3..b6fc1e949e34f 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS . Fixed bug GH-7757 (Multi-inherited final constant causes fatal error). (cmb) . Fixed zend_fibers.c build with ZEND_FIBER_UCONTEXT. (Petr Sumbera) + . Added riscv64 support for fibers. (Jeremie Courreges-Anglas) - Filter: . Fixed FILTER_FLAG_NO_RES_RANGE flag. (Yifan Tong) diff --git a/Zend/asm/jump_riscv64_sysv_elf_gas.S b/Zend/asm/jump_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5417e5d5e3498 --- /dev/null +++ b/Zend/asm/jump_riscv64_sysv_elf_gas.S @@ -0,0 +1,150 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "jump_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack for GP + FPU + addi sp, sp, -0xd0 + + # save fs0 - fs11 + fsd fs0, 0x00(sp) + fsd fs1, 0x08(sp) + fsd fs2, 0x10(sp) + fsd fs3, 0x18(sp) + fsd fs4, 0x20(sp) + fsd fs5, 0x28(sp) + fsd fs6, 0x30(sp) + fsd fs7, 0x38(sp) + fsd fs8, 0x40(sp) + fsd fs9, 0x48(sp) + fsd fs10, 0x50(sp) + fsd fs11, 0x58(sp) + + # save s0-s11, ra + sd s0, 0x60(sp) + sd s1, 0x68(sp) + sd s2, 0x70(sp) + sd s3, 0x78(sp) + sd s4, 0x80(sp) + sd s5, 0x88(sp) + sd s6, 0x90(sp) + sd s7, 0x98(sp) + sd s8, 0xa0(sp) + sd s9, 0xa8(sp) + sd s10, 0xb0(sp) + sd s11, 0xb8(sp) + sd ra, 0xc0(sp) + + # save RA as PC + sd ra, 0xc8(sp) + + # store SP (pointing to context-data) in A2 + mv a2, sp + + # restore SP (pointing to context-data) from A0 + mv sp, a0 + + # load fs0 - fs11 + fld fs0, 0x00(sp) + fld fs1, 0x08(sp) + fld fs2, 0x10(sp) + fld fs3, 0x18(sp) + fld fs4, 0x20(sp) + fld fs5, 0x28(sp) + fld fs6, 0x30(sp) + fld fs7, 0x38(sp) + fld fs8, 0x40(sp) + fld fs9, 0x48(sp) + fld fs10, 0x50(sp) + fld fs11, 0x58(sp) + + # load s0-s11,ra + ld s0, 0x60(sp) + ld s1, 0x68(sp) + ld s2, 0x70(sp) + ld s3, 0x78(sp) + ld s4, 0x80(sp) + ld s5, 0x88(sp) + ld s6, 0x90(sp) + ld s7, 0x98(sp) + ld s8, 0xa0(sp) + ld s9, 0xa8(sp) + ld s10, 0xb0(sp) + ld s11, 0xb8(sp) + ld ra, 0xc0(sp) + + # return transfer_t from jump + # pass transfer_t as first arg in context function + # a0 == FCTX, a1 == DATA + mv a0, a2 + + # load pc + ld a2, 0xc8(sp) + + # restore stack from GP + FPU + addi sp, sp, 0xd0 + + jr a2 +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/Zend/asm/make_riscv64_sysv_elf_gas.S b/Zend/asm/make_riscv64_sysv_elf_gas.S new file mode 100644 index 0000000000000..5322e0fdbdec7 --- /dev/null +++ b/Zend/asm/make_riscv64_sysv_elf_gas.S @@ -0,0 +1,91 @@ +/* + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt or copy at + http://www.boost.org/LICENSE_1_0.txt) +*/ +/******************************************************* + * * + * ------------------------------------------------- * + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | * + * ------------------------------------------------- * + * | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c| * + * ------------------------------------------------- * + * | fs0 | fs1 | fs2 | fs3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | * + * ------------------------------------------------- * + * | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c| * + * ------------------------------------------------- * + * | fs4 | fs5 | fs6 | fs7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | * + * ------------------------------------------------- * + * | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c| * + * ------------------------------------------------- * + * | fs8 | fs9 | fs10 | fs11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | * + * ------------------------------------------------- * + * | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c| * + * ------------------------------------------------- * + * | s0 | s1 | s2 | s3 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | * + * ------------------------------------------------- * + * | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c| * + * ------------------------------------------------- * + * | s4 | s5 | s6 | s7 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | * + * ------------------------------------------------- * + * | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc| * + * ------------------------------------------------- * + * | s8 | s9 | s10 | s11 | * + * ------------------------------------------------- * + * ------------------------------------------------- * + * | 48 | 49 | 50 | 51 | | | | | * + * ------------------------------------------------- * + * | 0xc0| 0xc4| 0xc8| 0xcc| | | | | * + * ------------------------------------------------- * + * | ra | pc | | | * + * ------------------------------------------------- * + * * + *******************************************************/ + +.file "make_riscv64_sysv_elf_gas.S" +.text +.align 1 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + # shift address in a0 (allocated stack) to lower 16 byte boundary + andi a0, a0, ~0xF + + # reserve space for context-data on context-stack + addi a0, a0, -0xd0 + + # third arg of make_fcontext() == address of context-function + # store address as a PC to jump in + sd a2, 0xc8(a0) + + # save address of finish as return-address for context-function + # will be entered after context-function returns (RA register) + lla a4, finish + sd a4, 0xc0(a0) + + ret // return pointer to context-data (a0) + +finish: + # exit code is zero + li a0, 0 + # exit application + tail _exit@plt + +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits diff --git a/configure.ac b/configure.ac index 754603c149f7c..03403eee5efe2 100644 --- a/configure.ac +++ b/configure.ac @@ -1201,6 +1201,7 @@ AS_CASE([$host_cpu], [arm*], [fiber_cpu="arm32"], [ppc64*|powerpc64*], [fiber_cpu="ppc64"], [ppc*|powerpc*], [fiber_cpu="ppc32"], + [riscv64*], [fiber_cpu="riscv64"], [s390x*], [fiber_cpu="s390x"], [mips64*], [fiber_cpu="mips64"], [mips*], [fiber_cpu="mips32"], @@ -1220,6 +1221,7 @@ AS_CASE([$fiber_cpu], [arm32], [fiber_asm_file_prefix="arm_aapcs"], [ppc64], [fiber_asm_file_prefix="ppc64_sysv"], [ppc32], [fiber_asm_file_prefix="ppc32_sysv"], + [riscv64], [fiber_asm_file_prefix="riscv64_sysv"], [s390x], [fiber_asm_file_prefix="s390x_sysv"], [mips64], [fiber_asm_file_prefix="mips64_n64"], [mips32], [fiber_asm_file_prefix="mips32_o32"], From d70c69839cd84799484b4d74b6769a8ab3de326a Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Tue, 4 Jan 2022 09:40:46 -0300 Subject: [PATCH 90/96] Prepare for PHP 8.0.16 --- NEWS | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 7f2292bc4a732..f7a7a1eefa56a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? 2022, PHP 8.0.15 +?? ??? 2022, PHP 8.0.16 + + +20 Jan 2022, PHP 8.0.15 - Core: . Fixed bug #81656 (GCC-11 silently ignores -R). (Michael Wallner) From f1d7f9570217a01e53bd62f82d27b74affd47c28 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 4 Jan 2022 13:08:33 +0100 Subject: [PATCH 91/96] [ci skip] Fix GH-7725: Adjust README instructions on referencing issues Also remove some references to git.php.net which is not used anymore. Closes GH-7882. --- README.md | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 18ee18a918489..e172501e92547 100644 --- a/README.md +++ b/README.md @@ -99,9 +99,8 @@ Extension Community Library - [PECL](https://pecl.php.net). ## Contributing The PHP source code is located in the Git repository at -[git.php.net](https://git.php.net). Contributions are most welcome by forking -the [GitHub mirror repository](https://github.com/php/php-src) and sending a -pull request. +[github.com/php/php-src](https://github.com/php/php-src). Contributions are most +welcome by forking the repository and sending a pull request. Discussions are done on GitHub, but depending on the topic can also be relayed to the official PHP developer mailing list internals@lists.php.net. @@ -111,20 +110,15 @@ New features require an RFC and must be accepted by the developers. See [Voting on PHP features](https://wiki.php.net/rfc/voting) for more information on the process. -Bug fixes **do not** require an RFC but require a bug tracker ticket. Open a -ticket at [bugs.php.net](https://bugs.php.net) and reference the bug id using -`#NNNNNN`. +Bug fixes don't require an RFC. If the bug has a GitHub issue, reference it in +the commit message using `GH-NNNNNN`. Use `#NNNNNN` for tickets in the old +[bugs.php.net](https://bugs.php.net) bug tracker. + Fix GH-7815: php_uname doesn't recognise latest Windows versions Fix #55371: get_magic_quotes_gpc() throws deprecation warning - After removing magic quotes, the get_magic_quotes_gpc function caused a - deprecated warning. get_magic_quotes_gpc can be used to detect the - magic_quotes behavior and therefore should not raise a warning at any time. - The patch removes this warning. - -Pull requests are not merged directly on GitHub. All PRs will be pulled and -pushed through [git.php.net](https://git.php.net). See -[Git workflow](https://wiki.php.net/vcs/gitworkflow) for more details. +See [Git workflow](https://wiki.php.net/vcs/gitworkflow) for details on how pull +requests are merged. ### Guidelines for contributors From 09165ace379e15418034141394225794494be617 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 29 Dec 2021 08:53:56 +0000 Subject: [PATCH 92/96] Fix ext/sockets build on Haiku The `SOCK_RDM` datagram option is unsupported on Haiku; instead `ifreq` has direct access to `ifr_index`. Closes GH-7849. --- NEWS | 2 ++ ext/sockets/multicast.c | 2 +- ext/sockets/sockets.c | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f7a7a1eefa56a..1c1cdde218b10 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2022, PHP 8.0.16 +- Sockets: + . Fixed ext/sockets build on Haiku. (David Carlier) 20 Jan 2022, PHP 8.0.15 diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c index 25203c0fbccae..d861d2f145ddf 100644 --- a/ext/sockets/multicast.c +++ b/ext/sockets/multicast.c @@ -718,7 +718,7 @@ int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_add return SUCCESS; } -#if !defined(ifr_ifindex) && defined(ifr_index) +#if !defined(ifr_ifindex) && (defined(ifr_index) || defined(__HAIKU__)) #define ifr_ifindex ifr_index #endif diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 16ad3e8013a4c..7976c9cc758a9 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -472,7 +472,9 @@ static PHP_MINIT_FUNCTION(sockets) REGISTER_LONG_CONSTANT("SOCK_DGRAM", SOCK_DGRAM, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_RAW", SOCK_RAW, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("SOCK_SEQPACKET",SOCK_SEQPACKET, CONST_CS | CONST_PERSISTENT); +#ifdef SOCK_RDM REGISTER_LONG_CONSTANT("SOCK_RDM", SOCK_RDM, CONST_CS | CONST_PERSISTENT); +#endif REGISTER_LONG_CONSTANT("MSG_OOB", MSG_OOB, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MSG_WAITALL", MSG_WAITALL, CONST_CS | CONST_PERSISTENT); From 3dbabf09fff6499abd5c1019e9e7b61183a548ad Mon Sep 17 00:00:00 2001 From: Patrick Allaert Date: Tue, 4 Jan 2022 19:02:01 +0100 Subject: [PATCH 93/96] Preparing for 8.1.2RC1 --- NEWS | 2 +- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index f8e11f0374868..36f91c61a6b6a 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.1.2 +06 Jan 2022, PHP 8.1.2RC1 - Core: . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) diff --git a/Zend/zend.h b/Zend/zend.h index a5de7fc883bec..a1475b0a1a419 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.2-dev" +#define ZEND_VERSION "4.1.2RC1" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 03403eee5efe2..23cb9df988a3d 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.2-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.2RC1],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index a7f9fd6c283c9..c41312c3f9494 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -3,6 +3,6 @@ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 #define PHP_RELEASE_VERSION 2 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.2-dev" +#define PHP_EXTRA_VERSION "RC1" +#define PHP_VERSION "8.1.2RC1" #define PHP_VERSION_ID 80102 From b54888a839893266ef3be759c04a09fdf51108cd Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 18 Jan 2022 17:22:21 -0600 Subject: [PATCH 94/96] Reset versions to -dev for the PHP-8.1.2 branch --- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index a1475b0a1a419..a5de7fc883bec 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.2RC1" +#define ZEND_VERSION "4.1.2-dev" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 23cb9df988a3d..03403eee5efe2 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.2RC1],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.2-dev],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index c41312c3f9494..a7f9fd6c283c9 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -3,6 +3,6 @@ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 #define PHP_RELEASE_VERSION 2 -#define PHP_EXTRA_VERSION "RC1" -#define PHP_VERSION "8.1.2RC1" +#define PHP_EXTRA_VERSION "-dev" +#define PHP_VERSION "8.1.2-dev" #define PHP_VERSION_ID 80102 From 3fefac77ec89bc93100ba9ce72b8304a9ab06166 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 18 Jan 2022 17:24:31 -0600 Subject: [PATCH 95/96] 8.1.2 GA --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 36f91c61a6b6a..f4c6710df556f 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -06 Jan 2022, PHP 8.1.2RC1 +20 Jan 2022, PHP 8.1.2 - Core: . Fixed bug #81216 (Nullsafe operator leaks dynamic property name). (Dmitry) From 899b6de55df3bb31f61778769e28ac9547305089 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 18 Jan 2022 17:27:15 -0600 Subject: [PATCH 96/96] Update versions for PHP 8.1.2 --- Zend/zend.h | 2 +- configure.ac | 2 +- main/php_version.h | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/zend.h b/Zend/zend.h index a5de7fc883bec..c13ebae6a689e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -20,7 +20,7 @@ #ifndef ZEND_H #define ZEND_H -#define ZEND_VERSION "4.1.2-dev" +#define ZEND_VERSION "4.1.2" #define ZEND_ENGINE_3 diff --git a/configure.ac b/configure.ac index 03403eee5efe2..5d4f682876190 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Basic autoconf initialization, generation of config.nice. dnl ---------------------------------------------------------------------------- AC_PREREQ([2.68]) -AC_INIT([PHP],[8.1.2-dev],[https://bugs.php.net],[php],[https://www.php.net]) +AC_INIT([PHP],[8.1.2],[https://bugs.php.net],[php],[https://www.php.net]) AC_CONFIG_SRCDIR([main/php_version.h]) AC_CONFIG_AUX_DIR([build]) AC_PRESERVE_HELP_ORDER diff --git a/main/php_version.h b/main/php_version.h index a7f9fd6c283c9..2a47f8f63b329 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -3,6 +3,6 @@ #define PHP_MAJOR_VERSION 8 #define PHP_MINOR_VERSION 1 #define PHP_RELEASE_VERSION 2 -#define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.1.2-dev" +#define PHP_EXTRA_VERSION "" +#define PHP_VERSION "8.1.2" #define PHP_VERSION_ID 80102