Skip to content

Commit

Permalink
[essentials] ensure WebUtils.ParseQueryString captures fragment param…
Browse files Browse the repository at this point in the history
…eters (#15662)

### Description of Change

Makes `WebUtils.ParseQueryString` extract parameters from both
`Uri.Query` and `Uri.Fragment`, resolving a regression from net8p4 to
net8p5.

### Issues Fixed

Fixes #15661
  • Loading branch information
jstedfast authored Jun 27, 2023
2 parents 15b10a2 + 4a9b908 commit 3b8e484
Showing 1 changed file with 17 additions and 9 deletions.
26 changes: 17 additions & 9 deletions src/Essentials/src/Types/Shared/WebUtils.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,31 @@ namespace Microsoft.Maui.ApplicationModel
{
static class WebUtils
{
// The following method is a port of the logic found in https://source.dot.net/#Microsoft.AspNetCore.WebUtilities/src/Shared/QueryStringEnumerable.cs
// but refactored such that it:
//
// 1. avoids the IEnumerable overhead that isn't needed (the ASP.NET logic was clearly designed that way to offer a public API whereas we don't need that)
// 2. avoids the use of unsafe code
internal static IDictionary<string, string> ParseQueryString(Uri uri)
{
var parameters = new Dictionary<string, string>(StringComparer.Ordinal);

if (uri == null || string.IsNullOrEmpty(uri.Query))
if (uri == null)
return parameters;

// Note: Uri.Query starts with a '?'
var query = uri.Query.AsSpan(1);
if (!string.IsNullOrEmpty(uri.Query))
UnpackParameters(uri.Query.AsSpan(1), parameters);

// Note: Uri.Fragment starts with a '#'
if (!string.IsNullOrEmpty(uri.Fragment))
UnpackParameters(uri.Fragment.AsSpan(1), parameters);

return parameters;
}

// The following method is a port of the logic found in https://source.dot.net/#Microsoft.AspNetCore.WebUtilities/src/Shared/QueryStringEnumerable.cs
// but refactored such that it:
//
// 1. avoids the IEnumerable overhead that isn't needed (the ASP.NET logic was clearly designed that way to offer a public API whereas we don't need that)
// 2. avoids the use of unsafe code
static void UnpackParameters(ReadOnlySpan<char> query, Dictionary<string, string> parameters)
{
while (!query.IsEmpty)
{
int delimeterIndex = query.IndexOf('&');
Expand Down Expand Up @@ -66,8 +76,6 @@ internal static IDictionary<string, string> ParseQueryString(Uri uri)
parameters[name] = Uri.UnescapeDataString(value);
}
}

return parameters;
}

internal static Uri EscapeUri(Uri uri)
Expand Down

0 comments on commit 3b8e484

Please sign in to comment.