diff --git a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs index 626b21a8bf1212..ac2f17bca8372e 100644 --- a/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs +++ b/src/libraries/System.Collections.Immutable/src/System/Collections/Frozen/String/LengthBuckets.cs @@ -27,11 +27,11 @@ internal static class LengthBuckets return null; } - int arraySize = spread * MaxPerLength; + long expectedArraySize = (long)spread * MaxPerLength; #if NET - if (arraySize > Array.MaxLength) + if (expectedArraySize > Array.MaxLength) #else - if (arraySize > 0X7FFFFFC7) + if (expectedArraySize > 0X7FFFFFC7) #endif { // In the future we may lower the value, as it may be quite unlikely @@ -39,6 +39,8 @@ internal static class LengthBuckets return null; } + int arraySize = (int)expectedArraySize; + // Instead of creating a dictionary of lists or a multi-dimensional array // we rent a single dimension array, where every bucket has five slots. // The bucket starts at (key.Length - minLength) * 5. diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs index 61b2bea331f857..14c967ce573098 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenDictionaryTests.cs @@ -419,6 +419,19 @@ public void ContainsKey_WithNonAscii(int percentageWithNonAscii) Assert.All(expected, kvp => actual.ContainsKey(kvp.Key)); } + + [Fact] + [OuterLoop] + public void ToFrozenDictionary_WithExtremelyLargeStrings() + { + // Test case with extremely large strings that exceed length bucket boundaries. + var keys = new[] { "", new string('a', 0X7FFFFFC7 / 4) }; + var frozen = keys.ToFrozenDictionary(s => s, GetKeyIEqualityComparer()); + Assert.Equal(keys.Length, frozen.Count); + Assert.Equal(keys.Length, frozen.Keys.Length); + Assert.Equal(keys.Length, frozen.Values.Length); + Assert.All(keys, key => frozen.ContainsKey(key)); + } } public class FrozenDictionary_Generic_Tests_string_string_Default : FrozenDictionary_Generic_Tests_string_string diff --git a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs index 989292fe7b4f2d..a021dc2353b285 100644 --- a/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs +++ b/src/libraries/System.Collections.Immutable/tests/Frozen/FrozenSetTests.cs @@ -376,6 +376,17 @@ public void Contains_WithNonAscii(int percentageWithNonAscii) Assert.All(expected, s => actual.Contains(s)); } + + [Fact] + [OuterLoop] + public void ToFrozenSet_WithExtremelyLargeStrings() + { + // Test case with extremely large strings that exceed length bucket boundaries. + var keys = new[] { "", new string('a', 0X7FFFFFC7 / 4) }; + var frozen = keys.ToFrozenSet(GetIEqualityComparer()); + Assert.Equal(keys.Length, frozen.Count); + Assert.All(keys, key => frozen.Contains(key)); + } } public class FrozenSet_Generic_Tests_string_Default : FrozenSet_Generic_Tests_string