]> granicus.if.org Git - php/commitdiff
Always remove HT iterators, even for uninit HT
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 1 Mar 2021 15:20:31 +0000 (16:20 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 1 Mar 2021 15:22:11 +0000 (16:22 +0100)
Fixes oss-fuzz #31423.

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

diff --git a/Zend/tests/array_splice_empty_ht_iter_removal.phpt b/Zend/tests/array_splice_empty_ht_iter_removal.phpt
new file mode 100644 (file)
index 0000000..1461827
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+HT iterator should be destroyed if array becomes empty during array_splice
+--FILE--
+<?php
+$a=[4];
+$i = 0;
+foreach ($a as &$r) {
+    var_dump($r);
+    $a = array_splice($a, 0);
+    if (++$i == 2) break;
+}
+?>
+--EXPECT--
+int(4)
+int(4)
index d35d8afd533e638fe0aa83db37334bb5c15e71b3..da150bd7984cc6a4fe0aaefad9d4dbe9c4dcfb7d 100644 (file)
@@ -1630,10 +1630,10 @@ ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
        } else if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
                goto free_ht;
        }
-       zend_hash_iterators_remove(ht);
        SET_INCONSISTENT(HT_DESTROYED);
        efree(HT_GET_DATA_ADDR(ht));
 free_ht:
+       zend_hash_iterators_remove(ht);
        FREE_HASHTABLE(ht);
 }