Skip to content

Commit

Permalink
Fixed logic for formatting IMAP FETCH HEADER.FIELDS.NOT corner case
Browse files Browse the repository at this point in the history
If IFetchRequest.Headers excludes References but IFetchRequest.Items includes References,
the formatted HEADER.FIELDS.NOT result contain REFERENCES, but it really shouldn't.

This commit fixes it so that IFetchRequest.Items References overrides this
such that the References exclude will be removed.
  • Loading branch information
jstedfast committed Jan 6, 2024
1 parent 0a2398b commit cb02ff5
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
10 changes: 9 additions & 1 deletion MailKit/Net/Imap/ImapFolderFetch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,11 @@ Task UntaggedFetchSummaryItemsHandler (ImapEngine engine, ImapCommand ic, int in
return Task.CompletedTask;
}

static bool IsEmptyExclude (HeaderSet headers, MessageSummaryItems items)
{
return headers.Exclude && (headers.Count == 0 || headers.Count == 1 && (items & MessageSummaryItems.References) != 0);
}

internal static string FormatSummaryItems (ImapEngine engine, IFetchRequest request, out bool previewText, bool isNotify = false)
{
var items = request.Items;
Expand Down Expand Up @@ -816,12 +821,15 @@ internal static string FormatSummaryItems (ImapEngine engine, IFetchRequest requ
}

if (request.Headers != null) {
if (request.Headers.Count == 0 && request.Headers.Exclude) {
if (IsEmptyExclude (request.Headers, request.Items)) {
tokens.Add ("BODY.PEEK[HEADER]");
} else if (request.Headers.Exclude) {
var headerFields = new StringBuilder ("BODY.PEEK[HEADER.FIELDS.NOT (");

foreach (var header in request.Headers) {
if ((request.Items & MessageSummaryItems.References) != 0 && header.Equals ("REFERENCES", StringComparison.Ordinal))
continue;

headerFields.Append (header);
headerFields.Append (' ');
}
Expand Down
43 changes: 43 additions & 0 deletions UnitTests/Net/Imap/ImapFolderFetchTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2038,5 +2038,48 @@ public void TestFormatFetchSummaryItemsAllHeaders ()
Assert.That (command, Is.EqualTo ("BODY.PEEK[HEADER]"));
}
}

[Test]
public void TestFormatFetchSummaryItemsHeaderFieldsAndReferences ()
{
using (var engine = new ImapEngine (null)) {
var request = new FetchRequest (MessageSummaryItems.References) {
Headers = new HeaderSet (new[] { HeaderId.InReplyTo })
};

var command = ImapFolder.FormatSummaryItems (engine, request, out var previewText);
Assert.That (command, Is.EqualTo ("BODY.PEEK[HEADER.FIELDS (IN-REPLY-TO REFERENCES)]"));
}
}

[Test]
public void TestFormatFetchSummaryItemsExcludeHeaderFieldsReferencesAndReferences ()
{
using (var engine = new ImapEngine (null)) {
var request = new FetchRequest (MessageSummaryItems.References) {
Headers = new HeaderSet (new[] { HeaderId.References }) {
Exclude = true
}
};

var command = ImapFolder.FormatSummaryItems (engine, request, out var previewText);
Assert.That (command, Is.EqualTo ("BODY.PEEK[HEADER]"));
}
}

[Test]
public void TestFormatFetchSummaryItemsExcludeHeaderFieldsInReplyToReferencesAndReferences ()
{
using (var engine = new ImapEngine (null)) {
var request = new FetchRequest (MessageSummaryItems.References) {
Headers = new HeaderSet (new[] { HeaderId.InReplyTo, HeaderId.References }) {
Exclude = true
}
};

var command = ImapFolder.FormatSummaryItems (engine, request, out var previewText);
Assert.That (command, Is.EqualTo ("BODY.PEEK[HEADER.FIELDS.NOT (IN-REPLY-TO)]"));
}
}
}
}

0 comments on commit cb02ff5

Please sign in to comment.