diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
index dfa0b3110..551551e8d 100644
--- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
+++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m
@@ -571,24 +571,27 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
case ActiveSyncMailFolder:
default:
{
+ NSMutableArray *addedOrChangedMessages;
SOGoMailObject *mailObject;
NSString *uid, *command;
NSDictionary *aMessage;
NSArray *allMessages;
-
+ int deleted_count;
+
allMessages = [theCollection syncTokenFieldsWithProperties: nil matchingSyncToken: theSyncKey fromDate: theFilterType];
-
+ addedOrChangedMessages = [NSMutableArray array];
+ deleted_count = 0;
+
// Check for the WindowSize.
// FIXME: we should eventually check for modseq and slice the maximum
// amount of messages returned to ensure we don't have the same
// modseq accross contiguous boundaries
max = [allMessages count];
- if (max > theWindowSize)
- {
- max = theWindowSize;
- more_available = YES;
- }
+ // We first check the number of deleted messages we have
+ // We do NOT honor the window size here as it seems to be
+ // impossible to get the modseq of an expunged message so
+ // we can't iterate in the list of deleted messages.
for (i = 0; i < max; i++)
{
aMessage = [allMessages objectAtIndex: i];
@@ -601,31 +604,53 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[s appendString: @""];
[s appendFormat: @"%@", uid];
[s appendString: @""];
+ deleted_count++;
}
else
{
- if ([command isEqualToString: @"added"])
- [s appendString: @""];
- else
- [s appendString: @""];
-
- mailObject = [theCollection lookupName: uid
- inContext: context
- acquire: 0];
-
- [s appendFormat: @"%@", uid];
- [s appendString: @""];
- [s appendString: [mailObject activeSyncRepresentationInContext: context]];
- [s appendString: @""];
-
- if ([command isEqualToString: @"added"])
- [s appendString: @""];
- else
- [s appendString: @""];
-
+ [addedOrChangedMessages addObject: aMessage];
}
}
+ // We then "pad" with our added/changed messages. We ALWAYS
+ // at least return one if available
+ max = [addedOrChangedMessages count];
+
+ for (i = 0; i < max; i++)
+ {
+ aMessage = [addedOrChangedMessages objectAtIndex: i];
+
+ uid = [[[aMessage allKeys] lastObject] stringValue];
+ command = [[aMessage allValues] lastObject];
+
+ if ([command isEqualToString: @"added"])
+ [s appendString: @""];
+ else
+ [s appendString: @""];
+
+ mailObject = [theCollection lookupName: uid
+ inContext: context
+ acquire: 0];
+
+ [s appendFormat: @"%@", uid];
+ [s appendString: @""];
+ [s appendString: [mailObject activeSyncRepresentationInContext: context]];
+ [s appendString: @""];
+
+ if ([command isEqualToString: @"added"])
+ [s appendString: @""];
+ else
+ [s appendString: @""];
+
+
+ // We check if we must stop padding
+ if (i+1+deleted_count > theWindowSize)
+ {
+ more_available = YES;
+ break;
+ }
+ }
+
//
if (more_available)
{
diff --git a/NEWS b/NEWS
index 09a3bb241..4a3a731b5 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Bug fixes
- fixed encoding of mail folder name when creating a subfolder (#2637)
- fixed returned date format for email messages in Active Sync
- fixed missing 'name part' in address for email messages in Active Sync
+ - fixed race condition when syncing huge amount of deleted messages over Active Sync
2.2.0 (2014-02-24)
------------------
diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m
index abf4bf100..7f45ec814 100644
--- a/SoObjects/Mailer/SOGoMailFolder.m
+++ b/SoObjects/Mailer/SOGoMailFolder.m
@@ -1940,8 +1940,11 @@ static NSString *defaultUserID = @"anyone";
uid = [theId intValue];
result = [[imap4 client] fetchModseqForUid: uid];
modseq = [[[[result objectForKey: @"RawResponse"] objectForKey: @"fetch"] objectForKey: @"modseq"] intValue];
-
- tag = [NSString stringWithFormat: @"%d-%d", uid, modseq-1];
+
+ if (modseq < 1)
+ modseq = 1;
+
+ tag = [NSString stringWithFormat: @"%d-%d", uid, modseq];
}
return tag;
@@ -1999,7 +2002,7 @@ static NSString *defaultUserID = @"anyone";
// Check updated items
//
//
-// . uid fetch 1:* (FLAGS) (changedsince 171)
+// . uid fetch 1:* (UID) (changedsince 171)
//
// To get the modseq of a specific message:
//
@@ -2101,11 +2104,14 @@ static NSString *defaultUserID = @"anyone";
// We fetch deleted ones
if (highestmodseq > 0)
{
+ id uid;
+
uids = [self fetchUIDsOfVanishedItems: highestmodseq];
for (i = 0; i < [uids count]; i++)
{
- d = [NSDictionary dictionaryWithObject: @"deleted" forKey: [uids objectAtIndex: i]];
+ uid = [uids objectAtIndex: i];
+ d = [NSDictionary dictionaryWithObject: @"deleted" forKey: uid];
[allTokens addObject: d];
}
}