Skip to content

Commit b55489f

Browse files
committed
Consistency fixes for negative indexes
1 parent b83421e commit b55489f

File tree

3 files changed

+13
-9
lines changed

3 files changed

+13
-9
lines changed

Zend/zend_hash.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_
180180
ht->nNumUsed = 0;
181181
ht->nNumOfElements = 0;
182182
ht->nInternalPointer = HT_INVALID_IDX;
183-
ht->nNextFreeElement = 0;
183+
ht->nNextFreeElement = ZEND_LONG_MIN;
184184
ht->pDestructor = pDestructor;
185185
ht->nTableSize = zend_hash_check_size(nSize);
186186
}
@@ -712,6 +712,10 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
712712
IS_CONSISTENT(ht);
713713
HT_ASSERT_RC1(ht);
714714

715+
if (h == ZEND_LONG_MIN && flag & HASH_ADD_NEXT) {
716+
h = 0;
717+
}
718+
715719
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
716720
CHECK_INIT(ht, h < ht->nTableSize);
717721
if (h < ht->nTableSize) {
@@ -795,8 +799,8 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
795799
ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
796800

797801
add_to_hash:
798-
/* If the first index is negative, dont force the next index to be 0 */
799-
if (UNEXPECTED((zend_long)h < 0 && ht->nNumOfElements == 0)) {
802+
/* Initialize nNextFreeElement with the value of the first numeric index */
803+
if (ht->nNextFreeElement == ZEND_LONG_MIN) {
800804
ht->nNextFreeElement = h;
801805
}
802806
idx = ht->nNumUsed++;
@@ -1400,7 +1404,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
14001404
}
14011405
ht->nNumUsed = 0;
14021406
ht->nNumOfElements = 0;
1403-
ht->nNextFreeElement = 0;
1407+
ht->nNextFreeElement = ZEND_LONG_MIN;
14041408
ht->nInternalPointer = HT_INVALID_IDX;
14051409
}
14061410

@@ -1439,7 +1443,7 @@ ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht)
14391443
}
14401444
ht->nNumUsed = 0;
14411445
ht->nNumOfElements = 0;
1442-
ht->nNextFreeElement = 0;
1446+
ht->nNextFreeElement = ZEND_LONG_MIN;
14431447
ht->nInternalPointer = HT_INVALID_IDX;
14441448
}
14451449

@@ -1776,7 +1780,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
17761780
target->nTableMask = HT_MIN_MASK;
17771781
target->nNumUsed = 0;
17781782
target->nNumOfElements = 0;
1779-
target->nNextFreeElement = 0;
1783+
target->nNextFreeElement = ZEND_LONG_MIN;
17801784
target->nInternalPointer = HT_INVALID_IDX;
17811785
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
17821786
} else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {

ext/standard/array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3266,7 +3266,7 @@ PHP_FUNCTION(array_pop)
32663266
ZVAL_DEREF(val);
32673267
ZVAL_COPY(return_value, val);
32683268

3269-
if (!p->key && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
3269+
if (!p->key && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
32703270
Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
32713271
}
32723272

ext/standard/tests/array/bug67693.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ echo"\nDone";
1616
?>
1717
--EXPECT--
1818
array(2) {
19-
[0]=>
19+
[-1]=>
2020
int(0)
21-
[1]=>
21+
[0]=>
2222
int(0)
2323
}
2424

0 commit comments

Comments
 (0)