@@ -314,8 +314,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
314
314
if (ht -> nTableSize >= HT_MAX_SIZE ) {
315
315
zend_error_noreturn (E_ERROR , "Possible integer overflow in memory allocation (%u * %zu + %zu)" , ht -> nTableSize * 2 , sizeof (Bucket ), sizeof (Bucket ));
316
316
}
317
- ht -> nTableSize += ht -> nTableSize ;
318
- 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 ));
317
+ uint32_t newTableSize = ht -> nTableSize * 2 ;
318
+ 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 ));
319
+ ht -> nTableSize = newTableSize ;
319
320
}
320
321
321
322
ZEND_API void ZEND_FASTCALL zend_hash_real_init (HashTable * ht , bool packed )
@@ -353,8 +354,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht)
353
354
ZEND_ASSERT (HT_SIZE_TO_MASK (nSize ));
354
355
355
356
HT_ASSERT_RC1 (ht );
356
- HT_FLAGS ( ht ) &= ~ HASH_FLAG_PACKED ;
357
+ // Alloc before assign to avoid inconsistencies on OOM
357
358
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
359
+ HT_FLAGS (ht ) &= ~HASH_FLAG_PACKED ;
358
360
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
359
361
HT_SET_DATA_ADDR (ht , new_data );
360
362
dst = ht -> arData ;
@@ -408,17 +410,18 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool
408
410
if (packed ) {
409
411
ZEND_ASSERT (HT_IS_PACKED (ht ));
410
412
if (nSize > ht -> nTableSize ) {
411
- ht -> nTableSize = zend_hash_check_size (nSize );
412
- 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 ));
413
+ uint32_t newTableSize = zend_hash_check_size (nSize );
414
+ 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 ));
415
+ ht -> nTableSize = newTableSize ;
413
416
}
414
417
} else {
415
418
ZEND_ASSERT (!HT_IS_PACKED (ht ));
416
419
if (nSize > ht -> nTableSize ) {
417
420
void * new_data , * old_data = HT_GET_DATA_ADDR (ht );
418
421
Bucket * old_buckets = ht -> arData ;
419
422
nSize = zend_hash_check_size (nSize );
420
- ht -> nTableSize = nSize ;
421
423
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
424
+ ht -> nTableSize = nSize ;
422
425
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
423
426
HT_SET_DATA_ADDR (ht , new_data );
424
427
memcpy (ht -> arData , old_buckets , sizeof (Bucket ) * ht -> nNumUsed );
@@ -1247,8 +1250,8 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
1247
1250
1248
1251
ZEND_ASSERT (HT_SIZE_TO_MASK (nSize ));
1249
1252
1250
- ht -> nTableSize = nSize ;
1251
1253
new_data = pemalloc (HT_SIZE_EX (nSize , HT_SIZE_TO_MASK (nSize )), GC_FLAGS (ht ) & IS_ARRAY_PERSISTENT );
1254
+ ht -> nTableSize = nSize ;
1252
1255
ht -> nTableMask = HT_SIZE_TO_MASK (ht -> nTableSize );
1253
1256
HT_SET_DATA_ADDR (ht , new_data );
1254
1257
memcpy (ht -> arData , old_buckets , sizeof (Bucket ) * ht -> nNumUsed );
0 commit comments