summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2018-09-14 10:28:31 +0300
committerDmitry Stogov <dmitry@zend.com>2018-09-14 10:28:31 +0300
commit3bc4a63fc27768c665fcbc101db4e579c761833b (patch)
tree394446c0b89de7d2f64b297574ee16369165a060
parent83685b52588ed62217abc07dec6b048ba580f137 (diff)
downloadphp-git-3bc4a63fc27768c665fcbc101db4e579c761833b.tar.gz
Fixed bug #76800 (foreach inconsistent if array modified during loop)
-rw-r--r--NEWS4
-rw-r--r--Zend/tests/bug76800.phpt13
-rw-r--r--Zend/zend_hash.c8
3 files changed, 22 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 8e9468e15d..952182f2cf 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2018, PHP 7.2.11
+- Core:
+ . Fixed bug #76800 (foreach inconsistent if array modified during loop).
+ (Dmitry)
+
- Opcache:
. Fixed bug #76832 (ZendOPcache.MemoryBase periodically deleted by the OS).
(Anatol)
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 f1b0c9b86c..80938694e5 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -932,9 +932,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++;