From e22702891dbbb2f5a9ed96d1d3592bbfbff19fa4 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Mon, 29 Apr 2019 01:28:48 +0100 Subject: [PATCH] Pass catchAll ValueTuple via in (#9807) --- src/Http/Routing/src/Matching/Candidate.cs | 2 +- src/Http/Routing/src/Matching/DfaMatcher.cs | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Http/Routing/src/Matching/Candidate.cs b/src/Http/Routing/src/Matching/Candidate.cs index 4493293251..cd390c4980 100644 --- a/src/Http/Routing/src/Matching/Candidate.cs +++ b/src/Http/Routing/src/Matching/Candidate.cs @@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Routing.Matching int score, KeyValuePair[] slots, (string parameterName, int segmentIndex, int slotIndex)[] captures, - (string parameterName, int segmentIndex, int slotIndex) catchAll, + in (string parameterName, int segmentIndex, int slotIndex) catchAll, (RoutePatternPathSegment pathSegment, int segmentIndex)[] complexSegments, KeyValuePair[] constraints) { diff --git a/src/Http/Routing/src/Matching/DfaMatcher.cs b/src/Http/Routing/src/Matching/DfaMatcher.cs index 441e53d556..e41fc44f6d 100644 --- a/src/Http/Routing/src/Matching/DfaMatcher.cs +++ b/src/Http/Routing/src/Matching/DfaMatcher.cs @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Routing.Matching // This is a fast path for single candidate, 0 policies and default selector if (candidateCount == 1 && policyCount == 0 && _isDefaultEndpointSelector) { - ref var candidate = ref candidates[0]; + ref readonly var candidate = ref candidates[0]; // Just strict path matching if (candidate.Flags == Candidate.CandidateFlags.None) @@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Routing.Matching // Reminder! // candidate: readonly data about the endpoint and how to match // state: mutable storarge for our processing - ref var candidate = ref candidates[i]; + ref readonly var candidate = ref candidates[i]; ref var state = ref candidateState[i]; state = new CandidateState(candidate.Endpoint, candidate.Score); @@ -249,13 +249,16 @@ namespace Microsoft.AspNetCore.Routing.Matching private void ProcessCatchAll( KeyValuePair[] slots, - (string parameterName, int segmentIndex, int slotIndex) catchAll, + in (string parameterName, int segmentIndex, int slotIndex) catchAll, string path, ReadOnlySpan segments) { - if (segments.Length > catchAll.segmentIndex) + // Read segmentIndex to local both to skip double read from stack value + // and to use the same in-bounds validated varaible to access the array. + var segmentIndex = catchAll.segmentIndex; + if ((uint)segmentIndex < (uint)segments.Length) { - var segment = segments[catchAll.segmentIndex]; + var segment = segments[segmentIndex]; slots[catchAll.slotIndex] = new KeyValuePair( catchAll.parameterName, path.Substring(segment.Start));