Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 2b6109b

Browse files
benaadamsstephentoub
authored andcommitted
Prevent concurrent use corruption from causing infinite loops (#16991)
Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
1 parent 3e610c2 commit 2b6109b

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

src/Common/src/CoreLib/System/Collections/Generic/Dictionary.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ private int FindEntry(TKey key)
364364
int i = -1;
365365
int[] buckets = _buckets;
366366
Entry[] entries = _entries;
367+
int collisionCount = 0;
367368
if (buckets != null)
368369
{
369370
IEqualityComparer<TKey> comparer = _comparer;
@@ -382,6 +383,13 @@ private int FindEntry(TKey key)
382383
}
383384

384385
i = entries[i].next;
386+
if (collisionCount >= entries.Length)
387+
{
388+
// The chain of entries forms a loop; which means a concurrent update has happened.
389+
// Break out of the loop and throw, rather than looping forever.
390+
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
391+
}
392+
collisionCount++;
385393
} while (true);
386394
}
387395
else
@@ -400,6 +408,13 @@ private int FindEntry(TKey key)
400408
}
401409

402410
i = entries[i].next;
411+
if (collisionCount >= entries.Length)
412+
{
413+
// The chain of entries forms a loop; which means a concurrent update has happened.
414+
// Break out of the loop and throw, rather than looping forever.
415+
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
416+
}
417+
collisionCount++;
403418
} while (true);
404419
}
405420
}
@@ -469,6 +484,12 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
469484
}
470485

471486
i = entries[i].next;
487+
if (collisionCount >= entries.Length)
488+
{
489+
// The chain of entries forms a loop; which means a concurrent update has happened.
490+
// Break out of the loop and throw, rather than looping forever.
491+
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
492+
}
472493
collisionCount++;
473494
} while (true);
474495
}
@@ -501,6 +522,12 @@ private bool TryInsert(TKey key, TValue value, InsertionBehavior behavior)
501522
}
502523

503524
i = entries[i].next;
525+
if (collisionCount >= entries.Length)
526+
{
527+
// The chain of entries forms a loop; which means a concurrent update has happened.
528+
// Break out of the loop and throw, rather than looping forever.
529+
ThrowHelper.ThrowInvalidOperationException_ConcurrentOperationsNotSupported();
530+
}
504531
collisionCount++;
505532
} while (true);
506533

0 commit comments

Comments
 (0)