diff options
-rw-r--r-- | src/mscorlib/Resources/Strings.resx | 3 | ||||
-rw-r--r-- | src/mscorlib/shared/System/Collections/Generic/Dictionary.cs | 27 | ||||
-rw-r--r-- | src/mscorlib/src/System/ThrowHelper.cs | 6 |
3 files changed, 36 insertions, 0 deletions
diff --git a/src/mscorlib/Resources/Strings.resx b/src/mscorlib/Resources/Strings.resx index 28346b2cf5..5d37b50f3c 100644 --- a/src/mscorlib/Resources/Strings.resx +++ b/src/mscorlib/Resources/Strings.resx @@ -2539,6 +2539,9 @@ <data name="InvalidOperation_CollectionCorrupted" xml:space="preserve"> <value>A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted.</value> </data> + <data name="InvalidOperation_ConcurrentOperationsNotSupported" xml:space="preserve"> + <value>Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.</value> + </data> <data name="InvalidOperation_ConstructorNotAllowedOnInterface" xml:space="preserve"> <value>Interface cannot have constructors.</value> </data> diff --git a/src/mscorlib/shared/System/Collections/Generic/Dictionary.cs b/src/mscorlib/shared/System/Collections/Generic/Dictionary.cs index 77d3055337..16b7cdc130 100644 --- a/src/mscorlib/shared/System/Collections/Generic/Dictionary.cs +++ b/src/mscorlib/shared/System/Collections/Generic/Dictionary.cs @@ -364,6 +364,7 @@ namespace System.Collections.Generic int i = -1; int[] buckets = _buckets; Entry[] entries = _entries; + int collisionCount = 0; if (buckets != null) { IEqualityComparer<TKey> comparer = _comparer; @@ -382,6 +383,13 @@ namespace System.Collections.Generic } i = entries[i].next; + if (collisionCount >= entries.Length) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported(); + } + collisionCount++; } while (true); } else @@ -400,6 +408,13 @@ namespace System.Collections.Generic } i = entries[i].next; + if (collisionCount >= entries.Length) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported(); + } + collisionCount++; } while (true); } } @@ -469,6 +484,12 @@ namespace System.Collections.Generic } i = entries[i].next; + if (collisionCount >= entries.Length) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported(); + } collisionCount++; } while (true); } @@ -501,6 +522,12 @@ namespace System.Collections.Generic } i = entries[i].next; + if (collisionCount >= entries.Length) + { + // The chain of entries forms a loop; which means a concurrent update has happened. + // Break out of the loop and throw, rather than looping forever. + ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported(); + } collisionCount++; } while (true); diff --git a/src/mscorlib/src/System/ThrowHelper.cs b/src/mscorlib/src/System/ThrowHelper.cs index 4eb92be31d..408b439c7e 100644 --- a/src/mscorlib/src/System/ThrowHelper.cs +++ b/src/mscorlib/src/System/ThrowHelper.cs @@ -284,6 +284,11 @@ namespace System throw GetInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); } + internal static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported() + { + throw GetInvalidOperationException(ExceptionResource.InvalidOperation_ConcurrentOperationsNotSupported); + } + internal static void ThrowArraySegmentCtorValidationFailedExceptions(Array array, int offset, int count) { throw GetArraySegmentCtorValidationFailedException(array, offset, count); @@ -591,6 +596,7 @@ namespace System AsyncMethodBuilder_InstanceNotInitialized, ArgumentNull_SafeHandle, NotSupported_StringComparison, + InvalidOperation_ConcurrentOperationsNotSupported, } } |