mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 10:58:10 +01:00
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.
This commit is contained in:
parent
882b994c17
commit
2c262042ac
1 changed files with 1 additions and 2 deletions
|
@ -55,8 +55,7 @@ struct maildir_flag_tag flag2tag[] = {
|
||||||
{ 'F', "flagged", false},
|
{ 'F', "flagged", false},
|
||||||
{ 'P', "passed", false},
|
{ 'P', "passed", false},
|
||||||
{ 'R', "replied", false},
|
{ 'R', "replied", false},
|
||||||
{ 'S', "unread", true },
|
{ 'S', "unread", true }
|
||||||
{ 'T', "deleted", false},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* We end up having to call the destructor explicitly because we had
|
/* We end up having to call the destructor explicitly because we had
|
||||||
|
|
Loading…
Reference in a new issue