Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/Shared/WebEncoders/WebEncoders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ namespace Microsoft.Extensions.Internal;
#endif
static class WebEncoders
{
#if NET9_0_OR_GREATER
/// <summary>SearchValues for the two Base64 and two Base64Url chars that differ from each other.</summary>
private static readonly SearchValues<char> s_base64vsBase64UrlDifferentiators = SearchValues.Create("+/-_");
#endif

/// <summary>
/// Decodes a base64url-encoded string.
/// </summary>
Expand Down Expand Up @@ -69,9 +74,11 @@ public static byte[] Base64UrlDecode(string input, int offset, int count)

#if NET9_0_OR_GREATER
// Legacy behavior of Base64UrlDecode supports either Base64 or Base64Url input.
// If it doesn't have + or /, it can be treated as Base64Url.
// If it has a - or _, or if it doesn't have + or /, it can be treated as Base64Url.
// Searching for any of them allows us to stop the search as early as we know whether Base64Url should be used.
ReadOnlySpan<char> inputSpan = input.AsSpan(offset, count);
if (!inputSpan.ContainsAny('+', '/'))
int indexOfFirstDifferentiator = inputSpan.IndexOfAny(s_base64vsBase64UrlDifferentiators);
if (indexOfFirstDifferentiator < 0 || inputSpan[indexOfFirstDifferentiator] is '-' or '_')
{
return Base64Url.DecodeFromChars(inputSpan);
}
Expand Down Expand Up @@ -124,9 +131,11 @@ public static byte[] Base64UrlDecode(string input, int offset, char[] buffer, in

#if NET9_0_OR_GREATER
// Legacy behavior of Base64UrlDecode supports either Base64 or Base64Url input.
// If it doesn't have + or /, it can be treated as Base64Url.
// If it has a - or _, or if it doesn't have + or /, it can be treated as Base64Url.
// Searching for any of them allows us to stop the search as early as we know Base64Url should be used.
ReadOnlySpan<char> inputSpan = input.AsSpan(offset, count);
if (!inputSpan.ContainsAny('+', '/'))
int indexOfFirstDifferentiator = inputSpan.IndexOfAny(s_base64vsBase64UrlDifferentiators);
if (indexOfFirstDifferentiator < 0 || inputSpan[indexOfFirstDifferentiator] is '-' or '_')
{
return Base64Url.DecodeFromChars(inputSpan);
}
Expand Down