Skip to content

Commit 9e8aab6

Browse files
committed
If the first index is negative let the next one stay negative
1 parent bec91e1 commit 9e8aab6

File tree

5 files changed

+20
-12
lines changed

5 files changed

+20
-12
lines changed

Zend/zend_hash.c

Lines changed: 15 additions & 7 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) {
@@ -764,7 +768,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
764768
}
765769
zend_hash_iterators_update(ht, HT_INVALID_IDX, h);
766770
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
767-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
771+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
768772
}
769773
p->h = h;
770774
p->key = NULL;
@@ -786,7 +790,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
786790
}
787791
ZVAL_COPY_VALUE(&p->val, pData);
788792
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
789-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
793+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
790794
}
791795
return &p->val;
792796
}
@@ -795,14 +799,18 @@ 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:
802+
/* Initialize nNextFreeElement with the value of the first numeric index */
803+
if (ht->nNextFreeElement == ZEND_LONG_MIN) {
804+
ht->nNextFreeElement = h;
805+
}
798806
idx = ht->nNumUsed++;
799807
ht->nNumOfElements++;
800808
if (ht->nInternalPointer == HT_INVALID_IDX) {
801809
ht->nInternalPointer = idx;
802810
}
803811
zend_hash_iterators_update(ht, HT_INVALID_IDX, idx);
804812
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
805-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
813+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
806814
}
807815
p = ht->arData + idx;
808816
p->h = h;
@@ -1396,7 +1404,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
13961404
}
13971405
ht->nNumUsed = 0;
13981406
ht->nNumOfElements = 0;
1399-
ht->nNextFreeElement = 0;
1407+
ht->nNextFreeElement = ZEND_LONG_MIN;
14001408
ht->nInternalPointer = HT_INVALID_IDX;
14011409
}
14021410

@@ -1435,7 +1443,7 @@ ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht)
14351443
}
14361444
ht->nNumUsed = 0;
14371445
ht->nNumOfElements = 0;
1438-
ht->nNextFreeElement = 0;
1446+
ht->nNextFreeElement = ZEND_LONG_MIN;
14391447
ht->nInternalPointer = HT_INVALID_IDX;
14401448
}
14411449

@@ -1772,7 +1780,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
17721780
target->nTableMask = HT_MIN_MASK;
17731781
target->nNumUsed = 0;
17741782
target->nNumOfElements = 0;
1775-
target->nNextFreeElement = 0;
1783+
target->nNextFreeElement = ZEND_LONG_MIN;
17761784
target->nInternalPointer = HT_INVALID_IDX;
17771785
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
17781786
} 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
@@ -3252,7 +3252,7 @@ PHP_FUNCTION(array_pop)
32523252
ZVAL_DEREF(val);
32533253
ZVAL_COPY(return_value, val);
32543254

3255-
if (!p->key && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
3255+
if (!p->key && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
32563256
Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
32573257
}
32583258

ext/standard/tests/array/array_fill_variation1.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ array(2) {
120120
array(2) {
121121
[-10]=>
122122
int(100)
123-
[0]=>
123+
[-9]=>
124124
int(100)
125125
}
126126
-- Iteration 3 --

ext/standard/tests/array/array_fill_variation1_64bit.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ array(2) {
120120
array(2) {
121121
[-10]=>
122122
int(100)
123-
[0]=>
123+
[-9]=>
124124
int(100)
125125
}
126126
-- Iteration 3 --

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)