# HG changeset patch # User Timo Sirainen # Date 1487174714 -7200 # Node ID 8004757eeee0f869a62031b2956d0b33ee797568 # Parent 7dfa73aba5f640464de86abf98a28bc55cc76795 lib-storage: Make sure mailbox undeletion won't go to infinite loop diff -r 7dfa73aba5f6 -r 8004757eeee0 src/lib-storage/mail-storage-private.h --- a/src/lib-storage/mail-storage-private.h Wed Feb 15 23:32:52 2017 +0200 +++ b/src/lib-storage/mail-storage-private.h Wed Feb 15 18:05:14 2017 +0200 @@ -395,6 +395,8 @@ unsigned int creating:1; /* Mailbox is being deleted */ unsigned int deleting:1; + /* Mailbox is being undeleted */ + unsigned int mailbox_undeleting:1; /* Don't use MAIL_INDEX_SYNC_FLAG_DELETING_INDEX for sync flag */ unsigned int delete_sync_check:1; /* Delete mailbox only if it's empty */ diff -r 7dfa73aba5f6 -r 8004757eeee0 src/lib-storage/mail-storage.c --- a/src/lib-storage/mail-storage.c Wed Feb 15 23:32:52 2017 +0200 +++ b/src/lib-storage/mail-storage.c Wed Feb 15 18:05:14 2017 +0200 @@ -1136,6 +1136,8 @@ { time_t mtime; + i_assert(!box->mailbox_undeleting); + if ((box->flags & MAILBOX_FLAG_READONLY) != 0) { /* most importantly we don't do this because we want to avoid a loop: mdbox storage rebuild -> mailbox_open() -> @@ -1148,7 +1150,10 @@ if (mtime + MAILBOX_DELETE_RETRY_SECS > time(NULL)) return FALSE; - if (mailbox_mark_index_deleted(box, FALSE) < 0) + box->mailbox_undeleting = TRUE; + int ret = mailbox_mark_index_deleted(box, FALSE); + box->mailbox_undeleting = FALSE; + if (ret < 0) return FALSE; box->mailbox_deleted = FALSE; return TRUE; @@ -1165,7 +1170,7 @@ } if (mailbox_open_full(box, NULL) < 0) { - if (!box->mailbox_deleted) + if (!box->mailbox_deleted || box->mailbox_undeleting) return -1; /* mailbox has been marked as deleted. if this deletion