| File: System\Net\Mail\DotAtomReader.cs | Web Access |
| Project: src\runtime\src\libraries\System.Net.Mail\src\System.Net.Mail.csproj (System.Net.Mail) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Net.Mime; using System.Text; namespace System.Net.Mail { // // RFC 2822 Section 3.2.4 - Atom, Dot-Atom // // A Dot-Atom is a string of ASCII characters separated by dots. Dots would normally not be allowed at the start // or end, but we do allow dots at the end for compatibility with other mail clients. We don't allow // multiple consecutive dots as specified in RFC 2822 section 3.4.1. // internal static class DotAtomReader { // Reads a Dot Atom in reverse. // // Preconditions: // - Index must be within the bounds of the data string. // // Return value: // - The first index of a character not valid in a dot-atom. It is then up to the caller to // determine if the next character is a valid delimiter. // e.g. "user.name@domain.com", starting at index 19 (m) returns 9 (@). // e.g. "user.name@dom in.com", starting at index 19 (m) returns 13 (space). // - -1 if the dot-atom section terminated at the start of the data string. // e.g. "user.name@domain.com", starting at index 8 (e) returns -1. // // Throws FormatException or returns false if: // - The initial character at data[index] is invalid in a dot-atom. // e.g. "a@b.com", starting at index 1 (@). // - The leading character is a dot. // e.g. "a@.b.com", starting at index 7 (m), throws because the leading char (index 2) is a dot. // internal static bool TryReadReverse(string data, int index, out int outIndex, bool throwExceptionIfFail) { Debug.Assert(0 <= index && index < data.Length, $"index was outside the bounds of the string: {index}"); int startIndex = index; // Scan for the first invalid chars (including whitespace) for (; 0 <= index; index--) { if (Ascii.IsValid(data[index]) // Any ASCII allowed && ((data[index] != MailBnfHelper.Dot && !MailBnfHelper.Atext[data[index]]) || (data[index] == MailBnfHelper.Dot && index > 0 && data[index - 1] == MailBnfHelper.Dot))) // Invalid char { break; } } // Check for empty/invalid dot-atom if (startIndex == index) { if (throwExceptionIfFail) { throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, data[index])); } else { outIndex = default; return false; } } else if (index > 0 && data[index] == MailBnfHelper.Dot && data[index - 1] == MailBnfHelper.Dot) { if (throwExceptionIfFail) { throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, MailBnfHelper.ConsecutiveDots)); } else { outIndex = default; return false; } } // Check for leading dot else if (data[index + 1] == MailBnfHelper.Dot) { if (throwExceptionIfFail) { throw new FormatException(SR.Format(SR.MailHeaderFieldInvalidCharacter, MailBnfHelper.Dot)); } else { outIndex = default; return false; } } outIndex = index; return true; } } }