Fix reported PriorityQueue issue. (#77229)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Mon, 24 Oct 2022 21:10:48 +0000 (22:10 +0100)
committerGitHub <noreply@github.com>
Mon, 24 Oct 2022 21:10:48 +0000 (22:10 +0100)
* Fix #77212.

* Remove unneeded using statement.

src/libraries/System.Collections/src/System/Collections/Generic/PriorityQueue.cs
src/libraries/System.Collections/tests/Generic/PriorityQueue/PriorityQueue.Generic.Tests.cs

index ede54d4..c1ee53a 100644 (file)
@@ -200,7 +200,7 @@ namespace System.Collections.Generic
             // Note that the node being enqueued does not need to be physically placed
             // there at this point, as such an assignment would be redundant.
 
-            int currentSize = _size++;
+            int currentSize = _size;
             _version++;
 
             if (_nodes.Length == currentSize)
@@ -208,6 +208,8 @@ namespace System.Collections.Generic
                 Grow(currentSize + 1);
             }
 
+            _size = currentSize + 1;
+
             if (_comparer == null)
             {
                 MoveUpDefaultComparer((element, priority), currentSize);
@@ -404,7 +406,7 @@ namespace System.Collections.Generic
             var collection = items as ICollection<(TElement Element, TPriority Priority)>;
             if (collection is not null && (count = collection.Count) > _nodes.Length - _size)
             {
-                Grow(_size + count);
+                Grow(checked(_size + count));
             }
 
             if (_size == 0)
@@ -464,10 +466,10 @@ namespace System.Collections.Generic
             ArgumentNullException.ThrowIfNull(elements);
 
             int count;
-            if (elements is ICollection<(TElement Element, TPriority Priority)> collection &&
+            if (elements is ICollection<TElement> collection &&
                 (count = collection.Count) > _nodes.Length - _size)
             {
-                Grow(_size + count);
+                Grow(checked(_size + count));
             }
 
             if (_size == 0)
index 555fee2..c50dfa9 100644 (file)
@@ -180,6 +180,33 @@ namespace System.Collections.Tests
             AssertExtensions.CollectionEqual(itemsToEnqueue, queue.UnorderedItems, EqualityComparer<(TElement, TPriority)>.Default);
         }
 
+        [Fact]
+        public void PriorityQueue_EnqueueRange_CollectionWithLargeCount_ThrowsOverflowException()
+        {
+            PriorityQueue<TElement, TPriority> queue = CreatePriorityQueue(1, 1, out List<(TElement element, TPriority priority)> generatedItems);
+
+            CollectionWithLargeCount<(TElement, TPriority)> pairCollection = new();
+            Assert.Throws<OverflowException>(() => queue.EnqueueRange(pairCollection));
+
+            (_, TPriority priority) = generatedItems[0];
+            CollectionWithLargeCount<TElement> elementCollection = new();
+            Assert.Throws<OverflowException>(() => queue.EnqueueRange(elementCollection, priority));
+        }
+
+        private class CollectionWithLargeCount<T> : ICollection<T>
+        {
+            public int Count => int.MaxValue;
+
+            public bool IsReadOnly => throw new NotImplementedException();
+            public void Add(T item) => throw new NotImplementedException();
+            public void Clear() => throw new NotImplementedException();
+            public bool Contains(T item) => throw new NotImplementedException();
+            public void CopyTo(T[] array, int arrayIndex) => throw new NotImplementedException();
+            public IEnumerator<T> GetEnumerator() => throw new NotImplementedException();
+            public bool Remove(T item) => throw new NotImplementedException();
+            IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
+        }
+
         [Theory]
         [MemberData(nameof(ValidCollectionSizes))]
         public void PriorityQueue_EnqueueDequeue(int count)