summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-07-07 11:57:01 +0200
committerNikita Popov <nikita.ppv@gmail.com>2020-07-07 11:58:25 +0200
commit64931fd3c4c7c3d217f2f19c997a8f89779727c5 (patch)
tree9050094d1a1108349d75932e4926e62b8a8da00c
parentb765f96f5f6d7d5da77e1d57f80b98f1fde16cde (diff)
downloadphp-git-64931fd3c4c7c3d217f2f19c997a8f89779727c5.tar.gz
Fixed bug #79792
We need to remove the iterators even if the array is empty (we will not create one if the first place, but the array may become empty after the fact).
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug79792.phpt16
-rw-r--r--Zend/zend_hash.c4
3 files changed, 20 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 279ce98c61..17289b59e0 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP NEWS
- Core:
. Fixed bug #79778 (Assertion failure if dumping closure with unresolved
static variable). (Nikita)
+ . Fixed bug #79792 (HT iterators not removed if empty array is destroyed).
+ (Nikita)
- COM:
. Fixed bug #63208 (BSTR to PHP string conversion not binary safe). (cmb)
diff --git a/Zend/tests/bug79792.phpt b/Zend/tests/bug79792.phpt
new file mode 100644
index 0000000000..85b98a907b
--- /dev/null
+++ b/Zend/tests/bug79792.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #79792: HT iterators not removed if empty array is destroyed
+--FILE--
+<?php
+$a = [42];
+foreach ($a as &$c) {
+ // Make the array empty.
+ unset($a[0]);
+ // Destroy the array.
+ $a = null;
+}
+?>
+===DONE===
+--EXPECTF--
+Warning: Invalid argument supplied for foreach() in %s on line %d
+===DONE===
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index 16fd24e3dc..2fb0eac448 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -1504,11 +1504,11 @@ ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
}
} while (++p != end);
}
- zend_hash_iterators_remove(ht);
- SET_INCONSISTENT(HT_DESTROYED);
} else if (EXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
goto free_ht;
}
+ zend_hash_iterators_remove(ht);
+ SET_INCONSISTENT(HT_DESTROYED);
efree(HT_GET_DATA_ADDR(ht));
free_ht:
FREE_HASHTABLE(ht);