diff --git a/Zend/tests/gh10085_1.phpt b/Zend/tests/gh10085_1.phpt deleted file mode 100644 index cc11c96a09d..00000000000 --- a/Zend/tests/gh10085_1.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -GH-10085: Assertion in add_function_array() ---FILE-- - ---EXPECT-- -array(2) { - [0]=> - array(2) { - [0]=> - array(0) { - } - [1]=> - int(0) - } - [1]=> - int(0) -} diff --git a/Zend/tests/gh10085_2.phpt b/Zend/tests/gh10085_2.phpt deleted file mode 100644 index 7895999f2cd..00000000000 --- a/Zend/tests/gh10085_2.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -GH-10085: Assertion in add_function_array() ---FILE-- - ---EXPECT-- -array(2) { - [0]=> - array(2) { - [0]=> - array(0) { - } - [1]=> - int(0) - } - [1]=> - int(0) -} diff --git a/Zend/tests/gh11171.phpt b/Zend/tests/gh11171.phpt new file mode 100644 index 00000000000..8bda7da0b7b --- /dev/null +++ b/Zend/tests/gh11171.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-11171: Test +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + &string(4) "test" +} diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 00286cac388..d16699d698f 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1039,22 +1039,16 @@ static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const cha static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */ { + if (result == op1 && Z_ARR_P(op1) == Z_ARR_P(op2)) { + /* $a += $a */ + return; + } if (result != op1) { ZVAL_ARR(result, zend_array_dup(Z_ARR_P(op1))); - zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0); - } else if (Z_ARR_P(op1) == Z_ARR_P(op2)) { - /* $a += $a */ } else { - /* We have to duplicate op1 (even with refcount == 1) because it may be an element of op2 - * and therefore its reference counter may be increased by zend_hash_merge(). That leads to - * an assertion in _zend_hash_add_or_update_i() that only allows adding elements to hash - * tables with RC1. See GH-10085 and Zend/tests/gh10085*.phpt */ - zval tmp; - ZVAL_ARR(&tmp, zend_array_dup(Z_ARR_P(op1))); - zend_hash_merge(Z_ARRVAL(tmp), Z_ARRVAL_P(op2), zval_add_ref, 0); - zval_ptr_dtor(result); - ZVAL_COPY_VALUE(result, &tmp); + SEPARATE_ARRAY(result); } + zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0); } /* }}} */