From b209f84e5895d7ae3b9ca200f36343d162914932 Mon Sep 17 00:00:00 2001 From: Michael Gratton Date: Wed, 23 Sep 2020 09:11:50 +1000 Subject: [PATCH 024/124] Geary.Imap.FolderSession: Ensure client session is selected when accessed Ensure the underlying ClientSession object is in the SELECTED state for the correct mailbox when obtaining it. --- src/engine/imap/api/imap-folder-session.vala | 31 ++++++++++++++++---- src/engine/imap/api/imap-session-object.vala | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/engine/imap/api/imap-folder-session.vala b/src/engine/imap/api/imap-folder-session.vala index 092c06cd..98db3088 100644 --- a/src/engine/imap/api/imap-folder-session.vala +++ b/src/engine/imap/api/imap-folder-session.vala @@ -38,6 +38,8 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { /** Determines if this folder accepts custom IMAP flags. */ public Trillian accepts_user_flags { get; private set; default = Trillian.UNKNOWN; } + private MailboxSpecifier mailbox; + private Quirks quirks; private Nonblocking.Mutex cmd_mutex = new Nonblocking.Mutex(); @@ -107,9 +109,9 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { session.search.connect(on_search); session.status_response_received.connect(on_status_response); - MailboxSpecifier mailbox = session.get_mailbox_for_path(folder.path); + this.mailbox = session.get_mailbox_for_path(folder.path); StatusResponse? response = yield session.select_async( - mailbox, cancellable + this.mailbox, cancellable ); throw_on_not_ok(response, "SELECT " + this.folder.path.to_string()); @@ -1107,8 +1109,6 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { Geary.EmailFlags? flags, GLib.DateTime? date_received) throws GLib.Error { - ClientSession session = claim_session(); - MessageFlags? msg_flags = null; if (flags != null) { Imap.EmailFlags imap_flags = Imap.EmailFlags.from_api_email_flags(flags); @@ -1121,9 +1121,8 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { if (date_received != null) internaldate = new InternalDate.from_date_time(date_received); - MailboxSpecifier mailbox = session.get_mailbox_for_path(this.folder.path); AppendCommand cmd = new AppendCommand( - mailbox, + this.mailbox, msg_flags, internaldate, message.get_rfc822_buffer(), @@ -1161,6 +1160,26 @@ private class Geary.Imap.FolderSession : Geary.Imap.SessionObject { ); } + /** + * Returns a valid IMAP client session for use by this object. + * + * In addition to the checks made by {@link + * SessionObject.claim_session}, this method also ensures that the + * IMAP session is in the SELECTED state for the correct mailbox. + */ + protected override ClientSession claim_session() + throws ImapError { + var session = base.claim_session(); + if (session.get_protocol_state() != SELECTED && + !this.mailbox.equal_to(session.selected_mailbox)) { + throw new ImapError.NOT_CONNECTED( + "IMAP object no longer SELECTED for %s", + this.mailbox.to_string() + ); + } + return session; + } + // HACK: See https://bugzilla.gnome.org/show_bug.cgi?id=714902 // // Detect when a server has returned a BAD response to FETCH diff --git a/src/engine/imap/api/imap-session-object.vala b/src/engine/imap/api/imap-session-object.vala index ee1ac09f..d47c6950 100644 --- a/src/engine/imap/api/imap-session-object.vala +++ b/src/engine/imap/api/imap-session-object.vala @@ -90,7 +90,7 @@ public abstract class Geary.Imap.SessionObject : BaseObject, Logging.Source { * or has been closed, or because the connection to the server was * lost. */ - protected ClientSession claim_session() + protected virtual ClientSession claim_session() throws ImapError { if (this.session == null || this.session.get_protocol_state() == NOT_CONNECTED) { -- 2.29.2