1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
This commit is contained in:
Nikita Popov
2015-12-17 22:11:08 +01:00
parent 0a1a4dc033
commit 6a4c02e107
3 changed files with 28 additions and 10 deletions

2
NEWS
View File

@@ -16,6 +16,8 @@ PHP NEWS
. Fixed bug #71089 (No check to duplicate zend_extension). (Remi)
. Fixed bug #71086 (Invalid numeric literal parse error within
highlight_string() function). (Nikita)
. Fixed bug #71154 (Incorrect HT iterator invalidation causes iterator reuse).
(Nikita)
- DBA:
. Fixed key leak with invalid resource. (Laruence)

19
Zend/tests/bug71154.phpt Normal file
View File

@@ -0,0 +1,19 @@
--TEST--
Bug #71154: Incorrect HT iterator invalidation causes iterator reuse
--FILE--
<?php
$array = [1, 2, 3];
foreach ($array as &$ref) {
/* Free array, causing free of iterator */
$array = [];
/* Reuse the iterator.
* However it will also be reused on next foreach iteration */
$it = new ArrayIterator([1, 2, 3]);
$it->rewind();
}
var_dump($it->current());
?>
--EXPECT--
int(1)

View File

@@ -31,6 +31,8 @@
# define HT_ASSERT(c)
#endif
#define HT_POISONED_PTR ((HashTable *) (intptr_t) -1)
#if ZEND_DEBUG
/*
#define HASH_MASK_CONSISTENCY 0xc0
@@ -371,7 +373,8 @@ ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTab
if (iter->pos == HT_INVALID_IDX) {
return HT_INVALID_IDX;
} else if (UNEXPECTED(iter->ht != ht)) {
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
&& EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
iter->ht->u.v.nIteratorsCount--;
}
if (EXPECTED(ht->u.v.nIteratorsCount != 255)) {
@@ -389,7 +392,8 @@ ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
ZEND_ASSERT(idx != (uint32_t)-1);
if (EXPECTED(iter->ht) && EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
&& EXPECTED(iter->ht->u.v.nIteratorsCount != 255)) {
iter->ht->u.v.nIteratorsCount--;
}
iter->ht = NULL;
@@ -406,20 +410,13 @@ static zend_never_inline void ZEND_FASTCALL _zend_hash_iterators_remove(HashTabl
{
HashTableIterator *iter = EG(ht_iterators);
HashTableIterator *end = iter + EG(ht_iterators_used);
uint32_t idx;
while (iter != end) {
if (iter->ht == ht) {
iter->ht = NULL;
iter->ht = HT_POISONED_PTR;
}
iter++;
}
idx = EG(ht_iterators_used);
while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
idx--;
}
EG(ht_iterators_used) = idx;
}
static zend_always_inline void zend_hash_iterators_remove(HashTable *ht)