Skip to content

Commit 8d2e863

Browse files
committed
Fix overflow in LengthBuckets for large strings
LengthBuckets.CreateLengthBucketsArrayIfAppropriate caused an integer overflow when calculating bucket array size for very large strings, resulting in a negative value being passed to ArrayPool<T>.Shared.Rent. This triggered an ArgumentOutOfRangeException when creating a FrozenDictionary with large strings approaching Array.MaxLength. Add an overflow check to prevent creating buckets when the calculation would overflow.
1 parent 4d8ec94 commit 8d2e863

File tree

1 file changed

+5
-3
lines changed
  • src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String

1 file changed

+5
-3
lines changed

src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,20 @@ internal static class LengthBuckets
2727
return null;
2828
}
2929

30-
int arraySize = spread * MaxPerLength;
30+
long expectedArraySize = (long)spread * MaxPerLength;
3131
#if NET
32-
if (arraySize > Array.MaxLength)
32+
if (expectedArraySize > Array.MaxLength)
3333
#else
34-
if (arraySize > 0X7FFFFFC7)
34+
if (expectedArraySize > 0X7FFFFFC7)
3535
#endif
3636
{
3737
// In the future we may lower the value, as it may be quite unlikely
3838
// to have a LOT of strings of different sizes.
3939
return null;
4040
}
4141

42+
int arraySize = (int)expectedArraySize;
43+
4244
// Instead of creating a dictionary of lists or a multi-dimensional array
4345
// we rent a single dimension array, where every bucket has five slots.
4446
// The bucket starts at (key.Length - minLength) * 5.

0 commit comments

Comments
 (0)