Permissions: Protect GetIdsFromPathReversed against invalid program exception (#20930)

* Updates to protect GetIdsFromPathReversed against invalid program exception.

* Apply suggestions from code review

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Andy Butland
2025-11-24 10:19:37 +01:00
committed by GitHub
parent 04f98a758d
commit 12611942ff
2 changed files with 14 additions and 5 deletions

View File

@@ -51,16 +51,23 @@ public static class StringExtensions
}
/// <summary>
/// Convert a path to node ids in the order from right to left (deepest to shallowest)
/// Convert a path to node ids in the order from right to left (deepest to shallowest).
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
/// <param name="path">The path string expected as a comma delimited collection of integers.</param>
/// <returns>An array of integers matching the provided path.</returns>
public static int[] GetIdsFromPathReversed(this string path)
{
ReadOnlySpan<char> pathSpan = path.AsSpan();
// Using the explicit enumerator (while/MoveNext) over the SpanSplitEnumerator in a foreach loop to avoid any compiler
// boxing of the ref struct enumerator.
// This prevents potential InvalidProgramException across compilers/JITs ("Cannot create boxed ByRef-like values.").
MemoryExtensions.SpanSplitEnumerator<char> pathSegmentsEnumerator = pathSpan.Split(Constants.CharArrays.Comma);
List<int> nodeIds = [];
foreach (Range rangeOfPathSegment in pathSpan.Split(Constants.CharArrays.Comma))
while (pathSegmentsEnumerator.MoveNext())
{
Range rangeOfPathSegment = pathSegmentsEnumerator.Current;
if (int.TryParse(pathSpan[rangeOfPathSegment], NumberStyles.Integer, CultureInfo.InvariantCulture, out int pathSegment))
{
nodeIds.Add(pathSegment);

View File

@@ -389,9 +389,11 @@ public class StringExtensionsTests
}
}
[TestCase(null, "")]
[TestCase("", "")]
[TestCase("1,2,3,4,5", "5,4,3,2,1")]
[TestCase("1,2,x,4,5", "5,4,2,1")]
public void GetIdsFromPathReversed(string input, string expected)
public void GetIdsFromPathReversed_ReturnsExpectedResult(string input, string expected)
{
var ids = input.GetIdsFromPathReversed();
Assert.AreEqual(expected, string.Join(",", ids));