Skip to content

Commit

Permalink
Endless recursion when using + on array in foreach
Browse files Browse the repository at this point in the history
This reverts commit 84b4020.

Fixes GH-11171

(cherry picked from commit dc20cd9)
  • Loading branch information
iluuu1994 authored and patrickallaert committed May 10, 2023
1 parent 691ff9f commit 520fc2d
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 61 deletions.
2 changes: 0 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,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)
Expand Down
22 changes: 0 additions & 22 deletions Zend/tests/gh10085_1.phpt

This file was deleted.

25 changes: 0 additions & 25 deletions Zend/tests/gh10085_2.phpt

This file was deleted.

15 changes: 15 additions & 0 deletions Zend/tests/gh11171.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
--TEST--
GH-11171: Test
--FILE--
<?php
$all = ['test'];
foreach ($all as &$item) {
$all += [$item];
}
var_dump($all);
?>
--EXPECT--
array(1) {
[0]=>
&string(4) "test"
}
18 changes: 6 additions & 12 deletions Zend/zend_operators.c
Original file line number Diff line number Diff line change
Expand Up @@ -965,22 +965,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);
}
/* }}} */

Expand Down

0 comments on commit 520fc2d

Please sign in to comment.