@@ -304,8 +304,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
304
304
if (ht -> nTableSize >= HT_MAX_SIZE ) {
305
305
zend_error_noreturn (E_ERROR , "Possible integer overflow in memory allocation (%u * %zu + %zu)" , ht -> nTableSize * 2 , sizeof (Bucket ), sizeof (Bucket ));
306
306
}
307
- ht -> nTableSize += ht -> nTableSize ;
308
- HT_SET_DATA_ADDR (ht , perealloc2 (HT_GET_DATA_ADDR (ht ), HT_PACKED_SIZE_EX (ht -> nTableSize , HT_MIN_MASK ), HT_PACKED_USED_SIZE (ht ), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT ));
307
+ uint32_t newTableSize = ht -> nTableSize * 2 ;
308
+ HT_SET_DATA_ADDR (ht , perealloc2 (HT_GET_DATA_ADDR (ht ), HT_PACKED_SIZE_EX (newTableSize , HT_MIN_MASK ), HT_PACKED_USED_SIZE (ht ), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT ));
309
+ ht -> nTableSize = newTableSize ;
309
310
}
310
311
311
312
ZEND_API void ZEND_FASTCALL zend_hash_real_init (HashTable * ht , bool packed )
@@ -343,8 +344,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht)
343
344
ZEND_ASSERT (HT_SIZE_TO_MASK (nSize ));
344
345
345
346
HT_ASSERT_RC1 (ht );
346
- HT_FLAGS ( ht ) &= ~ HASH_FLAG_PACKED ;
347
+ // Alloc before assign to avoid inconsistencies on OOM
347
348
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
349
+ HT_FLAGS (ht ) &= ~HASH_FLAG_PACKED ;
348
350
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
349
351
HT_SET_DATA_ADDR (ht , new_data );
350
352
dst = ht -> arData ;
@@ -398,17 +400,18 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool
398
400
if (packed ) {
399
401
ZEND_ASSERT (HT_IS_PACKED (ht ));
400
402
if (nSize > ht -> nTableSize ) {
401
- ht -> nTableSize = zend_hash_check_size (nSize );
402
- HT_SET_DATA_ADDR (ht , perealloc2 (HT_GET_DATA_ADDR (ht ), HT_PACKED_SIZE_EX (ht -> nTableSize , HT_MIN_MASK ), HT_PACKED_USED_SIZE (ht ), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT ));
403
+ uint32_t newTableSize = zend_hash_check_size (nSize );
404
+ HT_SET_DATA_ADDR (ht , perealloc2 (HT_GET_DATA_ADDR (ht ), HT_PACKED_SIZE_EX (newTableSize , HT_MIN_MASK ), HT_PACKED_USED_SIZE (ht ), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT ));
405
+ ht -> nTableSize = newTableSize ;
403
406
}
404
407
} else {
405
408
ZEND_ASSERT (!HT_IS_PACKED (ht ));
406
409
if (nSize > ht -> nTableSize ) {
407
410
void * new_data , * old_data = HT_GET_DATA_ADDR (ht );
408
411
Bucket * old_buckets = ht -> arData ;
409
412
nSize = zend_hash_check_size (nSize );
410
- ht -> nTableSize = nSize ;
411
413
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
414
+ ht -> nTableSize = nSize ;
412
415
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
413
416
HT_SET_DATA_ADDR (ht , new_data );
414
417
memcpy (ht -> arData , old_buckets , sizeof (Bucket ) * ht -> nNumUsed );
@@ -1237,8 +1240,8 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
1237
1240
1238
1241
ZEND_ASSERT (HT_SIZE_TO_MASK (nSize ));
1239
1242
1240
- ht -> nTableSize = nSize ;
1241
1243
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
1244
+ ht -> nTableSize = nSize ;
1242
1245
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
1243
1246
HT_SET_DATA_ADDR (ht , new_data );
1244
1247
memcpy (ht -> arData , old_buckets , sizeof (Bucket ) * ht -> nNumUsed );
0 commit comments