private static readonly SearchValues<char> s_validChars =
SearchValues.Create("-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz.");
- // For IRI, we're accepting anything non-ascii, so invert the condition to just check for invalid ascii characters
- private static readonly SearchValues<char> s_iriInvalidAsciiChars = SearchValues.Create(
+ // For IRI, we're accepting anything non-ascii (except 0x80-0x9F), so invert the condition to search for invalid ascii characters.
+ private static readonly SearchValues<char> s_iriInvalidChars = SearchValues.Create(
"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000A\u000B\u000C\u000D\u000E\u000F" +
"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F" +
- " !\"#$%&'()*+,/:;<=>?@[\\]^`{|}~\u007F");
+ " !\"#$%&'()*+,/:;<=>?@[\\]^`{|}~\u007F" +
+ "\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008A\u008B\u008C\u008D\u008E\u008F" +
+ "\u0090\u0091\u0092\u0093\u0094\u0095\u0096\u0097\u0098\u0099\u009A\u009B\u009C\u009D\u009E\u009F");
private static readonly SearchValues<char> s_asciiLetterUpperOrColonChars =
SearchValues.Create("ABCDEFGHIJKLMNOPQRSTUVWXYZ:");
public static bool IsValid(ReadOnlySpan<char> hostname, bool iri, bool notImplicitFile, out int length)
{
int invalidCharOrDelimiterIndex = iri
- ? hostname.IndexOfAny(s_iriInvalidAsciiChars)
+ ? hostname.IndexOfAny(s_iriInvalidChars)
: hostname.IndexOfAnyExcept(s_validChars);
if (invalidCharOrDelimiterIndex >= 0)
ReadOnlySpan<char> label = hostname.Slice(0, labelLength);
if (!Ascii.IsValid(label))
{
- // s_iriInvalidAsciiChars confirmed everything in [0, 7F] range.
- // Chars in [80, 9F] range are also invalid, check for them now.
- if (hostname.ContainsAnyInRange('\u0080', '\u009F'))
- {
- return false;
- }
-
// Account for the ACE prefix ("xn--")
labelLength += 4;