Skip to content

Commit 943c480

Browse files
committed
If the first index is negative let the next one stay negative
1 parent 9edf2e9 commit 943c480

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
@@ -181,7 +181,7 @@ static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize
181181
ht->nNumUsed = 0;
182182
ht->nNumOfElements = 0;
183183
ht->nInternalPointer = HT_INVALID_IDX;
184-
ht->nNextFreeElement = 0;
184+
ht->nNextFreeElement = ZEND_LONG_MIN;
185185
ht->pDestructor = pDestructor;
186186
ht->nTableSize = zend_hash_check_size(nSize);
187187
}
@@ -789,6 +789,10 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
789789
IS_CONSISTENT(ht);
790790
HT_ASSERT_RC1(ht);
791791

792+
if (h == ZEND_LONG_MIN && flag & HASH_ADD_NEXT) {
793+
h = 0;
794+
}
795+
792796
if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
793797
CHECK_INIT(ht, h < ht->nTableSize);
794798
if (h < ht->nTableSize) {
@@ -841,7 +845,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
841845
}
842846
zend_hash_iterators_update(ht, HT_INVALID_IDX, h);
843847
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
844-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
848+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
845849
}
846850
p->h = h;
847851
p->key = NULL;
@@ -863,7 +867,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
863867
}
864868
ZVAL_COPY_VALUE(&p->val, pData);
865869
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
866-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
870+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
867871
}
868872
return &p->val;
869873
}
@@ -872,14 +876,18 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
872876
ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
873877

874878
add_to_hash:
879+
/* Initialize nNextFreeElement with the value of the first numeric index */
880+
if (ht->nNextFreeElement == ZEND_LONG_MIN) {
881+
ht->nNextFreeElement = h;
882+
}
875883
idx = ht->nNumUsed++;
876884
ht->nNumOfElements++;
877885
if (ht->nInternalPointer == HT_INVALID_IDX) {
878886
ht->nInternalPointer = idx;
879887
}
880888
zend_hash_iterators_update(ht, HT_INVALID_IDX, idx);
881889
if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
882-
ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
890+
ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
883891
}
884892
p = ht->arData + idx;
885893
p->h = h;
@@ -1471,7 +1479,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
14711479
}
14721480
ht->nNumUsed = 0;
14731481
ht->nNumOfElements = 0;
1474-
ht->nNextFreeElement = 0;
1482+
ht->nNextFreeElement = ZEND_LONG_MIN;
14751483
ht->nInternalPointer = HT_INVALID_IDX;
14761484
}
14771485

@@ -1510,7 +1518,7 @@ ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht)
15101518
}
15111519
ht->nNumUsed = 0;
15121520
ht->nNumOfElements = 0;
1513-
ht->nNextFreeElement = 0;
1521+
ht->nNextFreeElement = ZEND_LONG_MIN;
15141522
ht->nInternalPointer = HT_INVALID_IDX;
15151523
}
15161524

@@ -1837,7 +1845,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
18371845
target->nTableMask = HT_MIN_MASK;
18381846
target->nNumUsed = 0;
18391847
target->nNumOfElements = 0;
1840-
target->nNextFreeElement = 0;
1848+
target->nNextFreeElement = ZEND_LONG_MIN;
18411849
target->nInternalPointer = HT_INVALID_IDX;
18421850
HT_SET_DATA_ADDR(target, &uninitialized_bucket);
18431851
} 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
@@ -3275,7 +3275,7 @@ PHP_FUNCTION(array_pop)
32753275
ZVAL_DEREF(val);
32763276
ZVAL_COPY(return_value, val);
32773277

3278-
if (!p->key && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
3278+
if (!p->key && p->h >= (zend_ulong)(Z_ARRVAL_P(stack)->nNextFreeElement - 1)) {
32793279
Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
32803280
}
32813281

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)