From 668c17e76c3daa7e8b5e2f8da0b42de4d1825395 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Oct 2026 23:29:41 +0500 Subject: [PATCH] Make PathHelper bounds checks explicit Use subtraction-based bounds checks in the AVX2, SSE2, and ARM64 paths to avoid relying on input size limits to prevent integer overflow. Add a Debug.Assert before creating the partial-pattern span to explicitly verify that its length is within the source string. This is a defensive refactoring, not a fix for an existing bug or reachable out-of-bounds memory access. Current callers supply strings, and CoreCLR's string length limit already prevents the original addition from overflowing. The change expresses the bounds requirements locally rather than relying on constraints enforced elsewhere. --- src/Ramstack.FileSystem.Globbing/Internal/PathHelper.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Ramstack.FileSystem.Globbing/Internal/PathHelper.cs b/src/Ramstack.FileSystem.Globbing/Internal/PathHelper.cs index 8afe664..e9ba214 100644 --- a/src/Ramstack.FileSystem.Globbing/Internal/PathHelper.cs +++ b/src/Ramstack.FileSystem.Globbing/Internal/PathHelper.cs @@ -111,7 +111,10 @@ public static ReadOnlySpan GetPartialPattern(string pattern, int depth) if (depth < 1 || r.final == length || IsGlobStar(ref s, r.start, r.final)) + { + Debug.Assert(r.final >= 0 && r.final <= pattern.Length); return MemoryMarshal.CreateReadOnlySpan(ref s, r.final); + } } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -246,7 +249,7 @@ public PathSegmentIterator() => return (start, _last); } - if (Avx2.IsSupported && (int)_position + Vector256.Count <= length) + if (Avx2.IsSupported && (int)_position <= length - Vector256.Count) { var chunk = LoadVector256(ref source, _position); var slash = Vector256.Create((ushort)'/'); @@ -266,7 +269,7 @@ public PathSegmentIterator() => if (_mask == 0) _position += Vector256.Count; } - else if (Sse2.IsSupported && !Avx2.IsSupported && (int)_position + Vector128.Count <= length) + else if (Sse2.IsSupported && !Avx2.IsSupported && (int)_position <= length - Vector128.Count) { var chunk = LoadVector128(ref source, _position); var slash = Vector128.Create((ushort)'/'); @@ -286,7 +289,7 @@ public PathSegmentIterator() => if (_mask == 0) _position += Vector128.Count; } - else if (AdvSimd.Arm64.IsSupported && (int)_position + Vector128.Count <= length) + else if (AdvSimd.Arm64.IsSupported && (int)_position <= length - Vector128.Count) { var chunk = LoadVector128(ref source, _position); var slash = Vector128.Create((ushort)'/');