diff options
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug76800.phpt | 13 | ||||
-rw-r--r-- | Zend/zend_hash.c | 8 |
3 files changed, 20 insertions, 3 deletions
@@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed bug #76869 (Incorrect bypassing protected method accessibilty check). (Dmitry) + . Fixed bug #76800 (foreach inconsistent if array modified during loop). + (Dmitry) 13 Sep 2018, PHP 7.3.0RC1 diff --git a/Zend/tests/bug76800.phpt b/Zend/tests/bug76800.phpt new file mode 100644 index 0000000000..d7f6d8070b --- /dev/null +++ b/Zend/tests/bug76800.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #76800 (foreach inconsistent if array modified during loop) +--FILE-- +<?php +$arr = [1 => 1, 3 => 3]; // [1 => 1, 2 => 3] will print both keys +foreach($arr as $key => &$val) { // without & will print both keys + echo "See key {$key}\n"; + $arr[0] = 0; // without this line will print both keys + unset($arr[0]); +} +--EXPECT-- +See key 1 +See key 3 diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 3a8815336d..3d5da267c4 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1114,9 +1114,11 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht) if (UNEXPECTED(ht->nInternalPointer == i)) { ht->nInternalPointer = j; } - if (UNEXPECTED(i == iter_pos)) { - zend_hash_iterators_update(ht, i, j); - iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1); + if (UNEXPECTED(i >= iter_pos)) { + do { + zend_hash_iterators_update(ht, iter_pos, j); + iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1); + } while (iter_pos < i); } q++; j++; |