From ef7db549a2b7badc644228f158e44d6bbdd1d992 Mon Sep 17 00:00:00 2001 From: Sebastian Holc Date: Sat, 9 Dec 2017 13:53:36 +0100 Subject: [PATCH 1/3] Fix null reference when failed to load email (corrupted/invalid mail file on the server) Skip email (don't add it to the returned list) instead of throwing an exception --- OpaqueMail/Imap/ImapClient.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpaqueMail/Imap/ImapClient.cs b/OpaqueMail/Imap/ImapClient.cs index 803cada..dee5573 100644 --- a/OpaqueMail/Imap/ImapClient.cs +++ b/OpaqueMail/Imap/ImapClient.cs @@ -2299,6 +2299,8 @@ private async void CheckIdle(object idleInitializedTimeObject) private async Task GetMessageHelper(string mailboxName, int id, bool headersOnly, bool setSeenFlag, bool isUid) { MessagePartialHelper helper = await GetMessagePartialHelper(mailboxName, id, headersOnly, setSeenFlag, -1, -1, isUid); + if (helper == null) + return null; MailMessage message = new MailMessage(helper.MessageString, ProcessingFlags); message.ImapUid = helper.ImapUid; From c62b8a14f7ec7c0c5f732451417d9997343a361e Mon Sep 17 00:00:00 2001 From: Sebastian Holc Date: Mon, 11 Dec 2017 10:05:05 +0100 Subject: [PATCH 2/3] Fix UID being 0 for all the messages. This first tries to parse UID using methods from 2.5.4 version (819518243dce6fb82e0c0d88cf8b06b772c62571), if it fails then tries to use the old method. --- OpaqueMail/Imap/ImapClient.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OpaqueMail/Imap/ImapClient.cs b/OpaqueMail/Imap/ImapClient.cs index dee5573..1e731d5 100644 --- a/OpaqueMail/Imap/ImapClient.cs +++ b/OpaqueMail/Imap/ImapClient.cs @@ -2378,14 +2378,17 @@ private async Task GetMessagePartialHelper(string mailboxN { // Read the message's UID and flags. int uid = 0; - if (!int.TryParse(Functions.ReturnBetween(response, "\r\n UID ", " "), out uid)) - { + int.TryParse(Functions.ReturnBetween(response, "\r\n UID ", " "), out uid); + if (uid == 0) int.TryParse(Functions.ReturnBetween(response, "\r\n UID ", ")"), out uid); - } - else if (!int.TryParse(Functions.ReturnBetween(response, "\r\nUID ", " "), out uid)) - { + if (uid == 0) + int.TryParse(Functions.ReturnBetween(response, "\r\nUID ", " "), out uid); + if (uid == 0) int.TryParse(Functions.ReturnBetween(response, "\r\nUID ", ")"), out uid); - } + if (uid == 0) + int.TryParse(Functions.ReturnBetween(response, "UID ", " "), out uid); + if (uid == 0) + int.TryParse(Functions.ReturnBetween(response, "UID ", ")"), out uid); string flagsString = Functions.ReturnBetween(response, "FLAGS (", ")"); // Strip IMAP response padding. From d8ab04024d6755e8e65e68a033c72ab6ee36e7a3 Mon Sep 17 00:00:00 2001 From: Sebastian Holc Date: Mon, 11 Dec 2017 11:25:53 +0100 Subject: [PATCH 3/3] Add optional headersOnly and setSeenFlag parameters to ImapClient.Search --- OpaqueMail/Imap/ImapClient.Synchronous.cs | 4 ++-- OpaqueMail/Imap/ImapClient.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpaqueMail/Imap/ImapClient.Synchronous.cs b/OpaqueMail/Imap/ImapClient.Synchronous.cs index be61ba2..fc8b510 100644 --- a/OpaqueMail/Imap/ImapClient.Synchronous.cs +++ b/OpaqueMail/Imap/ImapClient.Synchronous.cs @@ -697,9 +697,9 @@ public bool RenameMailbox(string currentMailboxName, string newMailboxName) /// Perform a search in the current mailbox and return all matching messages. /// /// Well-formatted IMAP search criteria. - public List Search(string searchQuery) + public List Search(string searchQuery, bool headersOnly = false, bool setSeenFlag = false) { - return Task.Run(() => SearchAsync(searchQuery)).Result; + return Task.Run(() => SearchAsync(searchQuery, headersOnly, setSeenFlag)).Result; } /// diff --git a/OpaqueMail/Imap/ImapClient.cs b/OpaqueMail/Imap/ImapClient.cs index 1e731d5..68acc90 100644 --- a/OpaqueMail/Imap/ImapClient.cs +++ b/OpaqueMail/Imap/ImapClient.cs @@ -1979,7 +1979,7 @@ public async Task RenameMailboxAsync(string currentMailboxName, string new /// Perform a search in the current mailbox and return all matching messages. /// /// Well-formatted IMAP search criteria. - public async Task> SearchAsync(string searchQuery) + public async Task> SearchAsync(string searchQuery, bool headersOnly = false, bool setSeenFlag = false) { // Protect against commands being called out of order. if (!IsAuthenticated) @@ -2009,7 +2009,7 @@ public async Task> SearchAsync(string searchQuery) int numericMessageID = -1; if (int.TryParse(messageID, out numericMessageID)) { - MailMessage message = await GetMessageAsync(int.Parse(messageID)); + MailMessage message = await GetMessageAsync(CurrentMailboxName, int.Parse(messageID), headersOnly, setSeenFlag); if (message != null) messages.Add(message); }