]> granicus.if.org Git - php/commitdiff
Fixed zend_hash_del()
authorDmitry Stogov <dmitry@zend.com>
Tue, 17 Mar 2015 20:13:39 +0000 (23:13 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 17 Mar 2015 20:13:39 +0000 (23:13 +0300)
Zend/zend_hash.c
Zend/zend_types.h

index a00f46e7b3788ce367321ab53bc90e492ccc5381..85242819ffaf8f7810ade9ce0acf998af90ef351 100644 (file)
@@ -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;
                        }
                }
index 09560943e574ef0095a459019502afcd8785ced8..3f1258f7bfa996b4c16ebfbc3fce25a8df84c797 100644 (file)
@@ -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