From 9857fe0e961aea417969fd265745428a372421bb Mon Sep 17 00:00:00 2001 From: Martin Costello Date: Tue, 30 Nov 2021 14:56:51 +0000 Subject: [PATCH] No-op ConcurrentStack.PushRange(T[]) if empty (#62126) * No-op ConcurrentStack.PushRange(T[]) if empty Resolves #62121. * Add more bounds checks Assert that ArgumentOutOfRangeException is thrown if specifying indexes for an empty array with PushRange(T[], int, int). * Review feedback Allow out-of-bounds index on empty array if count is zero. * Add extra test case Add a further test case for a non-empty array but with a count parameter value of zero. --- .../Collections/Concurrent/ConcurrentStack.cs | 3 +- .../tests/ConcurrentStackTests.cs | 32 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs index 04cb4e244f707..9a4af6b378c4f 100644 --- a/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs +++ b/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentStack.cs @@ -349,7 +349,6 @@ public void PushRange(T[] items, int startIndex, int count) if (count == 0) return; - Node head, tail; head = tail = new Node(items[startIndex]); for (int i = startIndex + 1; i < startIndex + count; i++) @@ -410,7 +409,7 @@ private static void ValidatePushPopRangeInput(T[] items, int startIndex, int cou throw new ArgumentOutOfRangeException(nameof(count), SR.ConcurrentStack_PushPopRange_CountOutOfRange); } int length = items.Length; - if (startIndex >= length || startIndex < 0) + if (startIndex > length || startIndex < 0) { throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ConcurrentStack_PushPopRange_StartOutOfRange); } diff --git a/src/libraries/System.Collections.Concurrent/tests/ConcurrentStackTests.cs b/src/libraries/System.Collections.Concurrent/tests/ConcurrentStackTests.cs index 51484a559afdd..9756b3ad97b42 100644 --- a/src/libraries/System.Collections.Concurrent/tests/ConcurrentStackTests.cs +++ b/src/libraries/System.Collections.Concurrent/tests/ConcurrentStackTests.cs @@ -63,6 +63,37 @@ public void PushRange_NoItems_NothingAdded() Assert.True(s.IsEmpty); } + [Fact] + public void PushRange_NoItems_NothingAdded_EmptyArrayWithRangeSpecified() + { + var s = new ConcurrentStack(); + Assert.True(s.IsEmpty); + + s.PushRange(new int[0], 0, 0); + Assert.True(s.IsEmpty); + } + + [Fact] + public void PushRange_NoItems_NothingAdded_NonEmptyArrayWithZeroCountSpecified() + { + var s = new ConcurrentStack(); + Assert.True(s.IsEmpty); + + int[] arr = new int[2]; + s.PushRange(arr, arr.Length, 0); + Assert.True(s.IsEmpty); + } + + [Fact] + public void PushRange_NoItems_NothingAdded_EmptyArrayNoRangeSpecified() + { + var s = new ConcurrentStack(); + Assert.True(s.IsEmpty); + + s.PushRange(new int[0]); + Assert.True(s.IsEmpty); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))] [InlineData(8, 10)] [InlineData(16, 100)] @@ -134,6 +165,7 @@ public void PushRange_InvalidArguments_Throws() Assert.Throws(() => stack.PushRange(new int[1], 0, -1)); Assert.Throws(() => stack.PushRange(new int[1], -1, 1)); Assert.Throws(() => stack.PushRange(new int[1], 2, 1)); + AssertExtensions.Throws(null, () => stack.PushRange(new int[0], 0, 1)); AssertExtensions.Throws(null, () => stack.PushRange(new int[1], 0, 10)); }