From 4eb6d57ec4de1d0c776faa71d74bba40cd394f92 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 3 Feb 2023 09:39:47 +0100 Subject: IMAPx: Folder refresh could remove new message from local summary It could happen that while the folder had been refreshing, another part added a new message to it, like a filter copying the message, which the refresh part evaluated as the new message in the summary had been removed, because it was not part of the 'known_uids', thus it had been removed from the local summary. The message was still available in the folder on the server, thus the next time the folder was refreshed it re-added the new messages back to the local summary. --- src/camel/providers/imapx/camel-imapx-server.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/camel/providers/imapx/camel-imapx-server.c b/src/camel/providers/imapx/camel-imapx-server.c index 3a30fa9d2..95918a022 100644 --- a/src/camel/providers/imapx/camel-imapx-server.c +++ b/src/camel/providers/imapx/camel-imapx-server.c @@ -5622,6 +5622,7 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is, CamelFolder *folder; CamelFolderChangeInfo *changes; GHashTable *known_uids; + GPtrArray *summary_uids = NULL; guint32 messages; guint32 unseen; guint32 uidnext; @@ -5739,6 +5740,14 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is, skip_old_flags_update = camel_imapx_server_skip_old_flags_update (camel_folder_get_parent_store (folder)); + if (!skip_old_flags_update) { + /* Remember summary state before running the update, in case there are + added new messages into the folder meanwhile, like with a COPY/MOVE filter; + such new messages would be considered removed, because not being part + of the 'known_uids' hash table. */ + summary_uids = camel_folder_summary_get_array (CAMEL_FOLDER_SUMMARY (imapx_summary)); + } + success = imapx_server_fetch_changes (is, mailbox, folder, known_uids, uidl, 0, cancellable, error); if (success && uidl != 1 && !skip_old_flags_update) success = imapx_server_fetch_changes (is, mailbox, folder, known_uids, 0, uidl, cancellable, error); @@ -5759,14 +5768,12 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is, if (success && !skip_old_flags_update) { GList *removed = NULL; - GPtrArray *array; gint ii; camel_folder_summary_lock (CAMEL_FOLDER_SUMMARY (imapx_summary)); - array = camel_folder_summary_get_array (CAMEL_FOLDER_SUMMARY (imapx_summary)); - for (ii = 0; array && ii < array->len; ii++) { - const gchar *uid = array->pdata[ii]; + for (ii = 0; summary_uids && ii < summary_uids->len; ii++) { + const gchar *uid = summary_uids->pdata[ii]; if (!uid) continue; @@ -5786,10 +5793,10 @@ camel_imapx_server_refresh_info_sync (CamelIMAPXServer *is, /* Shares UIDs with the 'array'. */ g_list_free (removed); } - - camel_folder_summary_free_array (array); } + g_clear_pointer (&summary_uids, camel_folder_summary_free_array); + camel_folder_summary_save (CAMEL_FOLDER_SUMMARY (imapx_summary), NULL); imapx_update_store_summary (folder); -- cgit v1.2.1