From 6f5bb3882cf5f332d97950dcb7785c6233af31cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrique=20J=2E=20Hern=C3=A1ndez=20Blasco?= Date: Wed, 21 Oct 2015 10:53:08 +0200 Subject: [PATCH] oc-mail: Sync expunged messages on first cache sync There is a use case where this has caused crashes: A message was hard-deleted using an IMAP client, this is the first message you deleted in that folder and you have cleared offline items in the client so a full sync is asked by upper layer. In that situation, the SyncLastDeleteChangeNumber version property is not set and return 0 in [getDeletedKeysFromChangeNumber:andCN:inTableType] making OpenChange to crash while it is asking for deleted fmids since a given change number. This is a regression from 18d7070c4a44a8437. --- OpenChange/MAPIStoreMailFolder.m | 53 +++++++++++++++----------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/OpenChange/MAPIStoreMailFolder.m b/OpenChange/MAPIStoreMailFolder.m index 9373bb0e5..7c8e4f8ac 100644 --- a/OpenChange/MAPIStoreMailFolder.m +++ b/OpenChange/MAPIStoreMailFolder.m @@ -594,8 +594,7 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) { BOOL rc = YES; uint64_t newChangeNum; - NSNumber *ti, *modseq, *initialLastModseq, *lastModseq, - *nextModseq; + NSNumber *ti, *modseq, *lastModseq, *nextModseq; NSString *changeNumber, *uid, *messageKey; uint64_t lastModseqNbr; EOQualifier *searchQualifier; @@ -634,7 +633,6 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) } lastModseq = [currentProperties objectForKey: @"SyncLastModseq"]; - initialLastModseq = lastModseq; if (lastModseq) { lastModseqNbr = [lastModseq unsignedLongLongValue]; @@ -718,40 +716,37 @@ _compareFetchResultsByMODSEQ (id entry1, id entry2, void *data) } /* 2. we synchronise expunged UIDs */ - if (initialLastModseq) + fetchResults = [(SOGoMailFolder *) sogoObject + fetchUIDsOfVanishedItems: lastModseqNbr]; + + max = [fetchResults count]; + + changeNumber = nil; + for (count = 0; count < max; count++) { - fetchResults = [(SOGoMailFolder *) sogoObject - fetchUIDsOfVanishedItems: lastModseqNbr]; - - max = [fetchResults count]; - - changeNumber = nil; - for (count = 0; count < max; count++) + uid = [[fetchResults objectAtIndex: count] stringValue]; + if ([messages objectForKey: uid]) { - uid = [[fetchResults objectAtIndex: count] stringValue]; - if ([messages objectForKey: uid]) + if (!changeNumber) { - if (!changeNumber) - { - newChangeNum = [[self context] getNewChangeNumber]; - changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum]; - } - [messages removeObjectForKey: uid]; - [self logWithFormat: @"Removed message entry for UID %@", uid]; - } - else - { - [self logWithFormat:@"Message entry not found for UID %@", uid]; + newChangeNum = [[self context] getNewChangeNumber]; + changeNumber = [NSString stringWithUnsignedLongLong: newChangeNum]; } + [messages removeObjectForKey: uid]; + [self logWithFormat: @"Removed message entry for UID %@", uid]; } - if (changeNumber) + else { - [currentProperties setObject: changeNumber - forKey: @"SyncLastDeleteChangeNumber"]; - [mapping setObject: lastModseq forKey: changeNumber]; - foundChange = YES; + [self logWithFormat:@"Message entry not found for UID %@", uid]; } } + if (changeNumber) + { + [currentProperties setObject: changeNumber + forKey: @"SyncLastDeleteChangeNumber"]; + [mapping setObject: lastModseq forKey: changeNumber]; + foundChange = YES; + } if (foundChange) {