diff options
-rw-r--r-- | Zend/zend_hash.c | 10 | ||||
-rw-r--r-- | Zend/zend_types.h | 4 |
2 files changed, 10 insertions, 4 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index a00f46e7b3..85242819ff 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -807,6 +807,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht) if (UNEXPECTED(ht->nNumOfElements == 0)) { if (ht->u.flags & HASH_FLAG_INITIALIZED) { + ht->nNumUsed = 0; HT_HASH_RESET(ht); } return SUCCESS; @@ -864,15 +865,16 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx, HT_HASH(ht, p->h | ht->nTableMask) = Z_NEXT(p->val); } } - if (ht->nNumUsed - 1 == idx) { + if (HT_IDX_TO_HASH(ht->nNumUsed - 1) == idx) { do { ht->nNumUsed--; } while (ht->nNumUsed > 0 && (Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF)); } ht->nNumOfElements--; - if (ht->nInternalPointer == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) { - uint32_t new_idx = idx; + if (HT_IDX_TO_HASH(ht->nInternalPointer) == idx || UNEXPECTED(ht->u.v.nIteratorsCount)) { + uint32_t new_idx; + new_idx = idx = HT_HASH_TO_IDX(idx); while (1) { new_idx++; if (new_idx >= ht->nNumUsed) { @@ -1083,7 +1085,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h) if (h < ht->nNumUsed) { p = ht->arData + h; if (Z_TYPE(p->val) != IS_UNDEF) { - _zend_hash_del_el_ex(ht, h, p, NULL); + _zend_hash_del_el_ex(ht, HT_IDX_TO_HASH(h), p, NULL); return SUCCESS; } } diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 09560943e5..3f1258f7bf 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -209,12 +209,16 @@ struct _zend_array { ((Bucket*)((char*)(data) + (idx))) # define HT_IDX_TO_HASH(idx) \ ((idx) * sizeof(Bucket)) +# define HT_HASH_TO_IDX(idx) \ + ((idx) / sizeof(Bucket)) #elif SIZEOF_SIZE_T == 8 # define HT_MAX_SIZE 0x80000000 # define HT_HASH_TO_BUCKET_EX(data, idx) \ ((data) + (idx)) # define HT_IDX_TO_HASH(idx) \ (idx) +# define HT_HASH_TO_IDX(idx) \ + (idx) #else # error "Unknown SIZEOF_SIZE_T" #endif |