From 4f6b8ec35f35da66aa641a4cef06116cf609dbd7 Mon Sep 17 00:00:00 2001 From: Tomas Weinfurt Date: Mon, 14 Mar 2022 15:10:35 +0000 Subject: [PATCH] Merged PR 21713: [release/3.1] MSRC 68590 - newlines in domain literals block embedded CRLF by default. --- .../DataAnnotations/EmailAddressAttribute.cs | 9 +++++++++ .../DataAnnotations/EmailAddressAttributeTests.cs | 1 + src/System.Net.Mail/src/System/Net/Mail/MailAddress.cs | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs b/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs index 43b693cae928..7cce1824f3f2 100644 --- a/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs +++ b/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/EmailAddressAttribute.cs @@ -8,6 +8,10 @@ namespace System.ComponentModel.DataAnnotations AllowMultiple = false)] public sealed class EmailAddressAttribute : DataTypeAttribute { + private static readonly char[] s_newLines = new char[] { '\r', '\n' }; + private static bool s_allowFullDomainLiterals = + AppContext.TryGetSwitch("System.Net.AllowFullDomainLiterals", out bool enable) ? enable : false; + public EmailAddressAttribute() : base(DataType.EmailAddress) { @@ -28,6 +32,11 @@ public override bool IsValid(object value) return false; } + if (!s_allowFullDomainLiterals && valueAsString.IndexOfAny(s_newLines) >= 0) + { + return false; + } + // only return true if there is only 1 '@' character // and it is neither the first nor the last character int index = valueAsString.IndexOf('@'); diff --git a/src/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs b/src/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs index 35cd7ebe1d79..14ab8fd416c8 100644 --- a/src/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs +++ b/src/System.ComponentModel.Annotations/tests/System/ComponentModel/DataAnnotations/EmailAddressAttributeTests.cs @@ -35,6 +35,7 @@ protected override IEnumerable InvalidValues() yield return new TestCase(new EmailAddressAttribute(), "someName"); yield return new TestCase(new EmailAddressAttribute(), "someName@"); yield return new TestCase(new EmailAddressAttribute(), "someName@a@b.com"); + yield return new TestCase(new EmailAddressAttribute(), "someName@[\r\n\tsomeDomain]"); } [Fact] diff --git a/src/System.Net.Mail/src/System/Net/Mail/MailAddress.cs b/src/System.Net.Mail/src/System/Net/Mail/MailAddress.cs index fb7025bc7776..246f2040f768 100644 --- a/src/System.Net.Mail/src/System/Net/Mail/MailAddress.cs +++ b/src/System.Net.Mail/src/System/Net/Mail/MailAddress.cs @@ -15,6 +15,10 @@ namespace System.Net.Mail // public partial class MailAddress { + private static readonly char[] s_newLines = new char[] { '\r', '\n' }; + private static bool s_allowFullDomainLiterals = + AppContext.TryGetSwitch("System.Net.AllowFullDomainLiterals", out bool enable) ? enable : false; + // These components form an e-mail address when assembled as follows: // "EncodedDisplayname" private readonly Encoding _displayNameEncoding; @@ -152,6 +156,12 @@ private string GetHost(bool allowUnicode) throw new SmtpException(SR.Format(SR.SmtpInvalidHostName, Address), argEx); } } + + if (!s_allowFullDomainLiterals && domain.IndexOfAny(s_newLines) >= 0) + { + throw new SmtpException(SR.Format(SR.SmtpInvalidHostName, Address)); + } + return domain; }