diff --git a/HeaderCollection.cs b/HeaderCollection.cs index 436dae3..0788b3d 100644 --- a/HeaderCollection.cs +++ b/HeaderCollection.cs @@ -115,32 +115,48 @@ public T GetEnum(string name) where T : struct, IConvertible { return values.FirstOrDefault(x => x.ToString().Equals(value, StringComparison.OrdinalIgnoreCase)); } + private static string ReadUntil(string values, ref int start, params char[] until) { + char c, nil = '\0', q = nil; + var hash = new System.Collections.Generic.HashSet(until); + string value; + for (int i = start; i < values.Length; i++) { + c = values[i]; + if (q != nil ) { + if(q == c){ + q = nil; + } + } else if (c == '"' || c == '\'') { + q = c; + } else if (c == '<') { + q = '>'; + + } else if (hash.Contains(c)) { + value = values.Substring(start, i - start); + start = i + 1; + return value; + } + } + + value = values.Substring(start); + start = values.Length; + return value; + } + public MailAddress[] GetAddresses(string header) { string values = this[header].RawValue.Trim(); List addrs = new List(); - while (true) { - int semicolon = values.IndexOf(';'); - int comma = values.IndexOf(','); - if (comma < semicolon || semicolon == -1) semicolon = comma; - - int bracket = values.IndexOf('>'); - string temp = null; - if (semicolon == -1 && bracket == -1) { - if (values.Length > 0) addrs.Add(values.ToEmailAddress()); - return addrs.Where(x => x != null).ToArray(); - } else { - if (bracket > -1 && (semicolon == -1 || bracket < semicolon)) { - temp = values.Substring(0, bracket + 1); - values = values.Substring(temp.Length); - } else if (semicolon > -1 && (bracket == -1 || semicolon < bracket)) { - temp = values.Substring(0, semicolon); - values = values.Substring(semicolon + 1); - } - if (temp.Length > 0) - addrs.Add(temp.Trim().ToEmailAddress()); - values = values.Trim(); - } + + int i = 0; + string value; + MailAddress addr; + while (i < values.Length) { + value = ReadUntil(values, ref i, ';', ',', '\n'); + addr = value.ToEmailAddress(); + if (addr != null) + addrs.Add(addr); } + + return addrs.ToArray(); } diff --git a/Tests/Parsing.cs b/Tests/Parsing.cs index 07ec03c..b56b733 100644 --- a/Tests/Parsing.cs +++ b/Tests/Parsing.cs @@ -280,6 +280,7 @@ BUSINESS DEMANDS AND HOPE YOU WILL NOT BETRAY THE TRUST AND CONFIDENCE WHICH [TestMethod] public void TestBasicMimeMessage() { var msg = GetMessage(@"From: John Doe +To: ; example@example.com; John Doe MIME-Version: 1.0 Content-Type: multipart/mixed; boundary=""XXXXboundary text"" @@ -301,7 +302,17 @@ this is the attachment text --XXXXboundary text--"); msg.From.Should().Not.Be.Null(); - msg.Attachments.Count.Should().Equal(2); + msg.From.DisplayName.Should().Equal("John Doe"); + msg.From.Address.Should().Equal("example@example.com"); + + var to = msg.To.ToArray(); + to.Length.Should().Equal(3); + to[0].Address.Should().Equal("example@example.com"); + to[1].Address.Should().Equal("example@example.com"); + to[2].Address.Should().Equal("example@example.com"); + + msg.Attachments.Count.Should().Equal(1); + msg.AlternateViews.Count.Should().Equal(1); msg.Attachments.All(a => a.GetData().Any().Should().Be.True()); }