Skip to content

Commit

Permalink
Use IndexOfAnyValues in MailBnfHelper (#81486)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub authored Feb 1, 2023
1 parent 0b3703e commit d7a7e34
Showing 1 changed file with 27 additions and 56 deletions.
83 changes: 27 additions & 56 deletions src/libraries/System.Net.Mail/src/System/Net/Mail/MailBnfHelper.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Buffers;
using System.Diagnostics;
using System.Text;

Expand All @@ -17,15 +18,17 @@ internal static class MailBnfHelper
// characters allowed in domain literals
internal static readonly bool[] Dtext = CreateCharactersAllowedInDomainLiterals();

// characters allowed in header names
internal static readonly bool[] Ftext = CreateCharactersAllowedInHeaderNames();

// characters allowed in tokens
internal static readonly bool[] Ttext = CreateCharactersAllowedInTokens();

// characters allowed inside of comments
internal static readonly bool[] Ctext = CreateCharactersAllowedInComments();

private static readonly IndexOfAnyValues<char> s_charactersAllowedInHeaderNames =
// ftext = %d33-57 / %d59-126
IndexOfAnyValues.Create("!\"#$%&'()*+,-./0123456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~");

private static readonly IndexOfAnyValues<char> s_charactersAllowedInTokens =
// ttext = %d33-126 except '()<>@,;:\"/[]?='
IndexOfAnyValues.Create("!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz{|}~");

internal const char Quote = '\"';
internal const char Space = ' ';
internal const char Tab = '\t';
Expand Down Expand Up @@ -101,38 +104,6 @@ private static bool[] CreateCharactersAllowedInDomainLiterals()
return dtext;
}

private static bool[] CreateCharactersAllowedInHeaderNames()
{
// ftext = %d33-57 / %d59-126
var ftext = new bool[128];
for (int i = 33; i <= 57; i++) { ftext[i] = true; }
for (int i = 59; i <= 126; i++) { ftext[i] = true; }
return ftext;
}

private static bool[] CreateCharactersAllowedInTokens()
{
// ttext = %d33-126 except '()<>@,;:\"/[]?='
var ttext = new bool[128];
for (int i = 33; i <= 126; i++) { ttext[i] = true; }
ttext['('] = false;
ttext[')'] = false;
ttext['<'] = false;
ttext['>'] = false;
ttext['@'] = false;
ttext[','] = false;
ttext[';'] = false;
ttext[':'] = false;
ttext['\\'] = false;
ttext['"'] = false;
ttext['/'] = false;
ttext['['] = false;
ttext[']'] = false;
ttext['?'] = false;
ttext['='] = false;
return ttext;
}

private static bool[] CreateCharactersAllowedInComments()
{
// ctext- %d1-8 / %d11 / %d12 / %d14-31 / %33-39 / %42-91 / %93-127
Expand Down Expand Up @@ -175,14 +146,10 @@ internal static bool SkipCFWS(string data, ref int offset)

internal static void ValidateHeaderName(string data)
{
int offset = 0;
for (; offset < data.Length; offset++)
if (data.Length == 0 || data.AsSpan().IndexOfAnyExcept(s_charactersAllowedInHeaderNames) >= 0)
{
if (data[offset] > Ftext.Length || !Ftext[data[offset]])
throw new FormatException(SR.InvalidHeaderName);
}
if (offset == 0)
throw new FormatException(SR.InvalidHeaderName);
}
}

internal static string? ReadQuotedString(string data, ref int offset, StringBuilder? builder)
Expand Down Expand Up @@ -253,24 +220,28 @@ internal static void ValidateHeaderName(string data)
internal static string ReadToken(string data, ref int offset)
{
int start = offset;
for (; offset < data.Length; offset++)

if (start >= data.Length)
{
if (!Ascii.IsValid(data[offset]))
{
throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, data[offset]));
}
else if (!Ttext[data[offset]])
return string.Empty;
}

ReadOnlySpan<char> span = data.AsSpan(start);
int i = span.IndexOfAnyExcept(s_charactersAllowedInTokens);
if (i >= 0)
{
if (i == 0 || !Ascii.IsValid(span[i]))
{
break;
throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, span[i]));
}
}

if (start == offset && offset < data.Length)
else
{
throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, data[offset]));
i = span.Length;
}

return data.Substring(start, offset - start);
offset += i;
return data.Substring(start, i);
}

private static readonly string?[] s_months = new string?[] { null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
Expand Down Expand Up @@ -328,7 +299,7 @@ internal static void GetTokenOrQuotedString(string data, StringBuilder builder,
continue;
}

if (!Ttext[data[offset]] || data[offset] == ' ')
if (!s_charactersAllowedInTokens.Contains(data[offset]) || data[offset] == ' ')
{
builder.Append('"');
for (; offset < data.Length; offset++)
Expand Down

0 comments on commit d7a7e34

Please sign in to comment.