]> granicus.if.org Git - php/commitdiff
Fixed bug #79792
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 7 Jul 2020 09:57:01 +0000 (11:57 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 7 Jul 2020 09:58:25 +0000 (11:58 +0200)
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).

NEWS
Zend/tests/bug79792.phpt [new file with mode: 0644]
Zend/zend_hash.c

diff --git a/NEWS b/NEWS
index 279ce98c6179edb71423d88f1330ac984eb3e048..17289b59e0433b51e38a2381cb008812ebf25f94 100644 (file)
--- 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 (file)
index 0000000..85b98a9
--- /dev/null
@@ -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===
index 16fd24e3dc28c6f8129501548d718355ed9b0eae..2fb0eac448fdc20d5453ce0c435610f627950419 100644 (file)
@@ -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);