From b889211003b35e6c5161da27bb8e39f30a2da958 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 14:59:52 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #122 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Collections/issues/122 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..4fe59b30 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Collections/issues/122 +Your prepared branch: issue-122-c8ce967d +Your prepared working directory: /tmp/gh-issue-solver-1757764784363 + +Proceed. \ No newline at end of file From 4b9e6fc7595999a3f8a4d2422dc5668e99fad344 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 15:06:05 +0300 Subject: [PATCH 2/3] Fix IndexOutOfRangeException when using negative indices in array extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add bounds checking for negative indices in GetElementOrDefault methods - Add bounds checking for negative indices in TryGetElement methods - Both int and long versions of methods now properly handle index < 0 - Add comprehensive tests for negative index scenarios - Add experiment demonstrating the fix works correctly Previously, negative indices would cause IndexOutOfRangeException when accessing array[index]. Now negative indices return default values or false as expected. Fixes #122 πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../Platform.Collections.Tests/ArrayTests.cs | 24 +++++++++ .../Arrays/GenericArrayExtensions.cs | 8 +-- experiments/ExperimentApp.csproj | 14 ++++++ experiments/NegativeIndexExperiment.cs | 49 +++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 experiments/ExperimentApp.csproj create mode 100644 experiments/NegativeIndexExperiment.cs diff --git a/csharp/Platform.Collections.Tests/ArrayTests.cs b/csharp/Platform.Collections.Tests/ArrayTests.cs index 1b9e67fb..3a7b6256 100644 --- a/csharp/Platform.Collections.Tests/ArrayTests.cs +++ b/csharp/Platform.Collections.Tests/ArrayTests.cs @@ -20,5 +20,29 @@ public void GetElementTest() Assert.False(array.TryGetElement(10, out element)); Assert.Equal(0, element); } + + [Fact] + public void GetElementWithNegativeIndexTest() + { + var array = new int[] { 1, 2, 3 }; + + // Test GetElementOrDefault with negative index + Assert.Equal(0, array.GetElementOrDefault(-1)); + Assert.Equal(0, array.GetElementOrDefault(-10)); + + // Test TryGetElement with negative index + Assert.False(array.TryGetElement(-1, out int element)); + Assert.Equal(0, element); + Assert.False(array.TryGetElement(-10, out element)); + Assert.Equal(0, element); + + // Test long versions + Assert.Equal(0, array.GetElementOrDefault(-1L)); + Assert.Equal(0, array.GetElementOrDefault(-10L)); + Assert.False(array.TryGetElement(-1L, out element)); + Assert.Equal(0, element); + Assert.False(array.TryGetElement(-10L, out element)); + Assert.Equal(0, element); + } } } diff --git a/csharp/Platform.Collections/Arrays/GenericArrayExtensions.cs b/csharp/Platform.Collections/Arrays/GenericArrayExtensions.cs index 3f4966c7..2ff00e07 100644 --- a/csharp/Platform.Collections/Arrays/GenericArrayExtensions.cs +++ b/csharp/Platform.Collections/Arrays/GenericArrayExtensions.cs @@ -19,7 +19,7 @@ public static class GenericArrayExtensions /// Number type int to compare.Число Ρ‚ΠΈΠΏΠ° int для сравнСния. /// Array element or default value.Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ массива ΠΈΠ»ΠΈ ΠΆΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T GetElementOrDefault(this T[] array, int index) => array != null && array.Length > index ? array[index] : default; + public static T GetElementOrDefault(this T[] array, int index) => array != null && index >= 0 && array.Length > index ? array[index] : default; /// /// Π‘hecks whether the array exists, if so, checks the array length using the index variable type long, and if the array length is greater than the index - return array[index], otherwise - default value. @@ -30,7 +30,7 @@ public static class GenericArrayExtensions /// Number type long to compare.Число Ρ‚ΠΈΠΏΠ° long для сравнСния. /// Array element or default value.Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ массива ΠΈΠ»ΠΈ ΠΆΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T GetElementOrDefault(this T[] array, long index) => array != null && array.LongLength > index ? array[index] : default; + public static T GetElementOrDefault(this T[] array, long index) => array != null && index >= 0 && array.LongLength > index ? array[index] : default; /// /// Checks whether the array exist, if so, checks the array length using the index varible type int, and if the array length is greater than the index, set the element variable to array[index] and return . @@ -44,7 +44,7 @@ public static class GenericArrayExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetElement(this T[] array, int index, out T element) { - if (array != null && array.Length > index) + if (array != null && index >= 0 && array.Length > index) { element = array[index]; return true; @@ -68,7 +68,7 @@ public static bool TryGetElement(this T[] array, int index, out T element) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetElement(this T[] array, long index, out T element) { - if (array != null && array.LongLength > index) + if (array != null && index >= 0 && array.LongLength > index) { element = array[index]; return true; diff --git a/experiments/ExperimentApp.csproj b/experiments/ExperimentApp.csproj new file mode 100644 index 00000000..2d730307 --- /dev/null +++ b/experiments/ExperimentApp.csproj @@ -0,0 +1,14 @@ + + + + Exe + net8 + latest + enable + + + + + + + \ No newline at end of file diff --git a/experiments/NegativeIndexExperiment.cs b/experiments/NegativeIndexExperiment.cs new file mode 100644 index 00000000..adce21f3 --- /dev/null +++ b/experiments/NegativeIndexExperiment.cs @@ -0,0 +1,49 @@ +using System; +using Platform.Collections.Arrays; + +// This experiment demonstrates that the fix works correctly +public class Program +{ + public static void Main() + { + var array = new int[] { 1, 2, 3 }; + + Console.WriteLine("Testing GetElementOrDefault with negative index:"); + + // Before fix: This would throw IndexOutOfRangeException + // After fix: Returns default value (0) + var result1 = array.GetElementOrDefault(-1); + Console.WriteLine($"GetElementOrDefault(-1) = {result1}"); // Should be 0 + + var result2 = array.GetElementOrDefault(-10); + Console.WriteLine($"GetElementOrDefault(-10) = {result2}"); // Should be 0 + + Console.WriteLine("\nTesting TryGetElement with negative index:"); + + // Before fix: This would throw IndexOutOfRangeException + // After fix: Returns false and sets element to default + bool success1 = array.TryGetElement(-1, out int element1); + Console.WriteLine($"TryGetElement(-1, out element) = {success1}, element = {element1}"); // Should be false, 0 + + bool success2 = array.TryGetElement(-10, out int element2); + Console.WriteLine($"TryGetElement(-10, out element) = {success2}, element = {element2}"); // Should be false, 0 + + Console.WriteLine("\nTesting with long versions:"); + + var result3 = array.GetElementOrDefault(-1L); + Console.WriteLine($"GetElementOrDefault(-1L) = {result3}"); // Should be 0 + + bool success3 = array.TryGetElement(-1L, out int element3); + Console.WriteLine($"TryGetElement(-1L, out element) = {success3}, element = {element3}"); // Should be false, 0 + + Console.WriteLine("\nTesting with valid indices (should still work):"); + + var result4 = array.GetElementOrDefault(1); + Console.WriteLine($"GetElementOrDefault(1) = {result4}"); // Should be 2 + + bool success4 = array.TryGetElement(1, out int element4); + Console.WriteLine($"TryGetElement(1, out element) = {success4}, element = {element4}"); // Should be true, 2 + + Console.WriteLine("\nAll tests completed without exceptions!"); + } +} \ No newline at end of file From 60caacdfa8d125d7c03be8d287dfc4ed5d2dd1a7 Mon Sep 17 00:00:00 2001 From: konard Date: Sat, 13 Sep 2025 15:06:51 +0300 Subject: [PATCH 3/3] Remove CLAUDE.md - Claude command completed --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 4fe59b30..00000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Collections/issues/122 -Your prepared branch: issue-122-c8ce967d -Your prepared working directory: /tmp/gh-issue-solver-1757764784363 - -Proceed. \ No newline at end of file