From 2c262042ac174d7bc96d6035ab9c88bd0abe7f35 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 9 Nov 2010 15:48:46 -0800 Subject: [PATCH] lib: Remove the synchronization of 'T' flag with "deleted" tag. Tags in a notmuch database affect all messages with the identical message-ID. But maildir tags affect individual files. And since multiple files can contain the identical message-ID, there is not a one-to-one correspondence between messages affected by tags and flags. This is particularly dangerous with the 'T' (== "trashed") maildir flag and the corresponding "deleted" tag in the notmuch database. Since these flags/tags are often used to trigger irreversible deletion operations, the lack of one-to-one correspondence can be potentially dangerous. For example, consider the following sequence: 1. A third-party application is used to identify duplicate messages in the mail store, and mark all-but-one of each duplicate with the 'T' flag for subsequent deletion. 2. A "notmuch new" operation reads that 'T' flag, adding the "deleted" flag to the corresponding messages within the notmuch database. 3. A subsequent notmuch operation, (such as a "notmuch dump; notmuch restore" cycle) synchronized the "deleted" tag back to the mail store, applying the 'T' flag to all(!) filenames with duplicate message IDs. 4. A third-party application reads the 'T' flags and irreversibly deletes all mail messages which had any duplicates(!). In order to avoid this scenario, we simply refuse to synchronize the 'T' flag with the "deleted" tag. Instead, applications can set 'T' and act on it to delete files, or can set "deleted" and act on it to delete files. But in either case the semantics are clear and there is never dangerous propagation through the one-to-many mapping of notmuch message objects to files. --- lib/message.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/message.cc b/lib/message.cc index c2a9ebdf..80ff4ca9 100644 --- a/lib/message.cc +++ b/lib/message.cc @@ -55,8 +55,7 @@ struct maildir_flag_tag flag2tag[] = { { 'F', "flagged", false}, { 'P', "passed", false}, { 'R', "replied", false}, - { 'S', "unread", true }, - { 'T', "deleted", false}, + { 'S', "unread", true } }; /* We end up having to call the destructor explicitly because we had