oc-calendar: Fix import in SOGo exceptions from recurring series
According to [MS-OXICAL] Section 2.1.3.1.1.20.13, the EXDATE property must be written only if there are ocurrences from the series that have been deleted and before this commit ModifiedInstanceDates were also included. We check against every ExceptionInfo from exception ocurrences of the series to know if the ocurrence was deleted or only modified.pull/65/head
parent
3b0b43f28f
commit
6f44ec42c1
1
NEWS
1
NEWS
|
@ -5,6 +5,7 @@ Enhancements
|
||||||
- Improve sync speed from Outlook by non-reprocessing already downloaded unread mails
|
- Improve sync speed from Outlook by non-reprocessing already downloaded unread mails
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
|
- Fix exception modifications import in recurrence series
|
||||||
- Sent mails are not longer in Drafts folder using Outlook
|
- Sent mails are not longer in Drafts folder using Outlook
|
||||||
- Fix server side crash parsing rtf emails with images (with word97 format)
|
- Fix server side crash parsing rtf emails with images (with word97 format)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include <talloc.h>
|
#include <talloc.h>
|
||||||
|
|
||||||
|
#import <Foundation/NSTimeZone.h>
|
||||||
|
|
||||||
#import <NGCards/iCalCalendar.h>
|
#import <NGCards/iCalCalendar.h>
|
||||||
#import <NGCards/iCalRecurrenceRule.h>
|
#import <NGCards/iCalRecurrenceRule.h>
|
||||||
|
|
||||||
|
@ -41,7 +43,10 @@
|
||||||
@interface iCalCalendar (MAPIStoreRecurrence)
|
@interface iCalCalendar (MAPIStoreRecurrence)
|
||||||
|
|
||||||
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
|
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
|
||||||
fromRecurrencePattern: (struct RecurrencePattern *) rp;
|
fromRecurrencePattern: (struct RecurrencePattern *) rp
|
||||||
|
withExceptions: (struct ExceptionInfo *) exInfos
|
||||||
|
andExceptionCount: (uint16_t) exInfoCount
|
||||||
|
inTimeZone: (NSTimeZone *) tz;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
#import <Foundation/NSSet.h>
|
#import <Foundation/NSSet.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSTimeZone.h>
|
||||||
|
|
||||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
@ -48,6 +49,10 @@
|
||||||
|
|
||||||
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
|
- (void) setupRecurrenceWithMasterEntity: (iCalRepeatableEntityObject *) entity
|
||||||
fromRecurrencePattern: (struct RecurrencePattern *) rp
|
fromRecurrencePattern: (struct RecurrencePattern *) rp
|
||||||
|
withExceptions: (struct ExceptionInfo *) exInfos
|
||||||
|
andExceptionCount: (uint16_t) exInfoCount
|
||||||
|
inTimeZone: (NSTimeZone *) tz
|
||||||
|
|
||||||
{
|
{
|
||||||
NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
|
NSCalendarDate *startDate, *olEndDate, *untilDate, *exDate;
|
||||||
NSString *monthDay, *month;
|
NSString *monthDay, *month;
|
||||||
|
@ -214,9 +219,12 @@
|
||||||
|
|
||||||
/* exception dates:
|
/* exception dates:
|
||||||
- take all deleted instances
|
- take all deleted instances
|
||||||
- remove all modified instances from the above set
|
- remove all modified instances available in ExceptionInfo from the above set
|
||||||
- add remaining instances, in chronological order
|
- add remaining instances, in chronological order
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Heuristic to avoid these loops */
|
||||||
|
if (rp->DeletedInstanceCount != rp->ModifiedInstanceCount) {
|
||||||
exceptionDates = [NSMutableSet set];
|
exceptionDates = [NSMutableSet set];
|
||||||
for (count = 0; count < rp->DeletedInstanceCount; count++)
|
for (count = 0; count < rp->DeletedInstanceCount; count++)
|
||||||
{
|
{
|
||||||
|
@ -227,15 +235,19 @@
|
||||||
second: [startDate secondOfMinute]];
|
second: [startDate secondOfMinute]];
|
||||||
[exceptionDates addObject: exDate];
|
[exceptionDates addObject: exDate];
|
||||||
}
|
}
|
||||||
for (count = 0; count < rp->ModifiedInstanceCount; count++)
|
/* Read the exceptions to remove the instances that are modified and not deleted */
|
||||||
|
if (exInfos && exInfoCount > 0)
|
||||||
{
|
{
|
||||||
exDate
|
for (count = 0; count < exInfoCount; count++)
|
||||||
= [NSDate dateFromMinutesSince1601: rp->ModifiedInstanceDates[count]];
|
{
|
||||||
exDate = [exDate hour: [startDate hourOfDay]
|
/* The OriginalStartDate is in local time */
|
||||||
minute: [startDate minuteOfHour]
|
exDate = [NSDate dateFromMinutesSince1601: exInfos[count].OriginalStartDate];
|
||||||
second: [startDate secondOfMinute]];
|
exDate = [exDate dateByAddingYears: 0 months: 0 days: 0
|
||||||
|
hours: 0 minutes: 0
|
||||||
|
seconds: - [tz secondsFromGMT]];
|
||||||
[exceptionDates removeObject: exDate];
|
[exceptionDates removeObject: exDate];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
realExDates = [[exceptionDates allObjects]
|
realExDates = [[exceptionDates allObjects]
|
||||||
sortedArrayUsingSelector: @selector (compare:)];
|
sortedArrayUsingSelector: @selector (compare:)];
|
||||||
|
@ -243,6 +255,7 @@
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
[entity addToExceptionDates: [realExDates objectAtIndex: count]];
|
[entity addToExceptionDates: [realExDates objectAtIndex: count]];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
@implementation iCalEvent (MAPIStoreProperties)
|
@implementation iCalEvent (MAPIStoreProperties)
|
||||||
|
|
||||||
- (void) _setupEventRecurrence: (NSData *) mapiRecurrenceData
|
- (void) _setupEventRecurrence: (NSData *) mapiRecurrenceData
|
||||||
|
inTimeZone: (NSTimeZone *) tz
|
||||||
inMemCtx: (TALLOC_CTX *) memCtx
|
inMemCtx: (TALLOC_CTX *) memCtx
|
||||||
{
|
{
|
||||||
struct Binary_r *blob;
|
struct Binary_r *blob;
|
||||||
|
@ -87,9 +88,12 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
[(iCalCalendar *) parent
|
[(iCalCalendar *) parent setupRecurrenceWithMasterEntity: self
|
||||||
setupRecurrenceWithMasterEntity: self
|
fromRecurrencePattern: &pattern->RecurrencePattern
|
||||||
fromRecurrencePattern: &pattern->RecurrencePattern];
|
withExceptions: pattern->ExceptionInfo
|
||||||
|
andExceptionCount: pattern->ExceptionCount
|
||||||
|
inTimeZone: tz
|
||||||
|
];
|
||||||
//talloc_free (blob);
|
//talloc_free (blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +366,7 @@
|
||||||
value = [properties
|
value = [properties
|
||||||
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];
|
objectForKey: MAPIPropertyKey (PidLidAppointmentRecur)];
|
||||||
if (value)
|
if (value)
|
||||||
[self _setupEventRecurrence: value inMemCtx: memCtx];
|
[self _setupEventRecurrence: value inTimeZone: userTimeZone inMemCtx: memCtx];
|
||||||
|
|
||||||
/* alarm */
|
/* alarm */
|
||||||
[self _setupEventAlarmFromProperties: properties];
|
[self _setupEventAlarmFromProperties: properties];
|
||||||
|
|
Loading…
Reference in New Issue