diff --git a/NEWS b/NEWS index d958329b874..bbeb2ea6d28 100644 --- a/NEWS +++ b/NEWS @@ -22,8 +22,6 @@ PHP NEWS . Fix inconsistent float negation in constant expressions. (ilutov) . Fixed bug GH-8841 (php-cli core dump calling a badly formed function). (nielsdos) - . Fixed bug GH-10085 (Assertion when adding two arrays with += where the first - array is contained in the second). (ilutov) . Fixed bug GH-10737 (PHP 8.1.16 segfaults on line 597 of sapi/apache2handler/sapi_apache2.c). (nielsdos, ElliotNB) . Fixed bug GH-11028 (Heap Buffer Overflow in zval_undefined_cv.). (nielsdos) 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 35df118cb21..02ca378bd85 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1015,22 +1015,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); } /* }}} */