summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mscorlib/Resources/Strings.resx3
-rw-r--r--src/mscorlib/shared/System/Collections/Generic/Dictionary.cs27
-rw-r--r--src/mscorlib/src/System/ThrowHelper.cs6
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,
}
}