Skip to content

Commit dc20cd9

Browse files
committed
Endless recursion when using + on array in foreach
This reverts commit 84b4020. Fixes GH-11171
1 parent 43e267a commit dc20cd9

File tree

5 files changed

+21
-61
lines changed

5 files changed

+21
-61
lines changed

NEWS

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ PHP NEWS
1818
. Fix inconsistent float negation in constant expressions. (ilutov)
1919
. Fixed bug GH-8841 (php-cli core dump calling a badly formed function).
2020
(nielsdos)
21-
. Fixed bug GH-10085 (Assertion when adding two arrays with += where the first
22-
array is contained in the second). (ilutov)
2321
. Fixed bug GH-10737 (PHP 8.1.16 segfaults on line 597 of
2422
sapi/apache2handler/sapi_apache2.c). (nielsdos, ElliotNB)
2523
. Fixed bug GH-11028 (Heap Buffer Overflow in zval_undefined_cv.). (nielsdos)

Zend/tests/gh10085_1.phpt

Lines changed: 0 additions & 22 deletions
This file was deleted.

Zend/tests/gh10085_2.phpt

Lines changed: 0 additions & 25 deletions
This file was deleted.

Zend/tests/gh11171.phpt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
--TEST--
2+
GH-11171: Test
3+
--FILE--
4+
<?php
5+
$all = ['test'];
6+
foreach ($all as &$item) {
7+
$all += [$item];
8+
}
9+
var_dump($all);
10+
?>
11+
--EXPECT--
12+
array(1) {
13+
[0]=>
14+
&string(4) "test"
15+
}

Zend/zend_operators.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -965,22 +965,16 @@ static ZEND_COLD zend_never_inline void ZEND_FASTCALL zend_binop_error(const cha
965965

966966
static zend_never_inline void ZEND_FASTCALL add_function_array(zval *result, zval *op1, zval *op2) /* {{{ */
967967
{
968+
if (result == op1 && Z_ARR_P(op1) == Z_ARR_P(op2)) {
969+
/* $a += $a */
970+
return;
971+
}
968972
if (result != op1) {
969973
ZVAL_ARR(result, zend_array_dup(Z_ARR_P(op1)));
970-
zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
971-
} else if (Z_ARR_P(op1) == Z_ARR_P(op2)) {
972-
/* $a += $a */
973974
} else {
974-
/* We have to duplicate op1 (even with refcount == 1) because it may be an element of op2
975-
* and therefore its reference counter may be increased by zend_hash_merge(). That leads to
976-
* an assertion in _zend_hash_add_or_update_i() that only allows adding elements to hash
977-
* tables with RC1. See GH-10085 and Zend/tests/gh10085*.phpt */
978-
zval tmp;
979-
ZVAL_ARR(&tmp, zend_array_dup(Z_ARR_P(op1)));
980-
zend_hash_merge(Z_ARRVAL(tmp), Z_ARRVAL_P(op2), zval_add_ref, 0);
981-
zval_ptr_dtor(result);
982-
ZVAL_COPY_VALUE(result, &tmp);
975+
SEPARATE_ARRAY(result);
983976
}
977+
zend_hash_merge(Z_ARRVAL_P(result), Z_ARRVAL_P(op2), zval_add_ref, 0);
984978
}
985979
/* }}} */
986980

0 commit comments

Comments
 (0)