mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-06-08 03:49:47 +00:00
fix(calendar): Add negative timestamp support to use date before 1970-01-01. Fixes #4914 (partial)
This commit is contained in:
@@ -664,18 +664,23 @@ static Class iCalEventK = nil;
|
||||
cycle: (BOOL) _isCycle
|
||||
{
|
||||
NSString *format;
|
||||
unsigned int start, end;
|
||||
long long start, end;
|
||||
|
||||
start = (unsigned int) [_startDate timeIntervalSince1970];
|
||||
end = (unsigned int) [_endDate timeIntervalSince1970];
|
||||
start = (long long) [_startDate timeIntervalSince1970];
|
||||
end = (long long) [_endDate timeIntervalSince1970];
|
||||
|
||||
// vTODOs don't necessarily have start/end dates
|
||||
if (_isCycle)
|
||||
format = (@"(c_startdate = NULL OR c_startdate <= %u)"
|
||||
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %u)");
|
||||
else
|
||||
format = (@"(c_startdate = NULL OR c_startdate <= %u)"
|
||||
@" AND (c_enddate = NULL OR c_enddate >= %u)");
|
||||
if (start < 0 && end < 0) {
|
||||
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
|
||||
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %lld)");
|
||||
} else {
|
||||
if (_isCycle)
|
||||
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
|
||||
@" AND (c_cycleenddate = NULL OR c_cycleenddate >= %lld)");
|
||||
else
|
||||
format = (@"(c_startdate = NULL OR c_startdate <= %lld)"
|
||||
@" AND (c_enddate = NULL OR c_enddate >= %lld )");
|
||||
}
|
||||
|
||||
return [NSString stringWithFormat: format, end, start];
|
||||
}
|
||||
|
||||
@@ -1070,98 +1070,90 @@ static inline void _feedBlockWithDayBasedData (NSMutableDictionary *block, unsig
|
||||
withEvent: (NSArray *) event
|
||||
withNumber: (NSNumber *) number
|
||||
{
|
||||
int currentDayStart, startSecs, endsSecs, currentStart, eventStart,
|
||||
eventEnd, computedEventEnd, offset, recurrenceTime, swap;
|
||||
int offset, recurrenceTime;
|
||||
long long startSecs, endsSecs, swap, currentDayStart, currentStart, eventStart,
|
||||
eventEnd, computedEventEnd;
|
||||
NSMutableArray *currentDay;
|
||||
NSMutableDictionary *eventBlock;
|
||||
NSString *userState;
|
||||
|
||||
eventStart = [[event objectAtIndex: eventStartDateIndex] intValue];
|
||||
if (eventStart < 0)
|
||||
[self errorWithFormat: @"event '%@' has negative start: %d (skipped)",
|
||||
[event objectAtIndex: eventNameIndex], eventStart];
|
||||
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
|
||||
|
||||
if ((eventEnd < eventStart && eventEnd > 0)
|
||||
|| (eventStart > 0 && eventEnd < 0)
|
||||
|| (eventStart > eventEnd && eventStart < 0 && eventEnd < 0))
|
||||
{
|
||||
swap = eventStart;
|
||||
eventStart = eventEnd;
|
||||
eventEnd = swap;
|
||||
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
|
||||
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
|
||||
}
|
||||
|
||||
startSecs = (long long) [startDate timeIntervalSince1970];
|
||||
endsSecs = (long long) [endDate timeIntervalSince1970];
|
||||
|
||||
if ([[event objectAtIndex: eventIsCycleIndex] boolValue])
|
||||
recurrenceTime = [[event objectAtIndex: eventRecurrenceIdIndex] unsignedIntValue];
|
||||
else
|
||||
recurrenceTime = 0;
|
||||
|
||||
currentStart = eventStart;
|
||||
if (currentStart < startSecs)
|
||||
{
|
||||
currentStart = startSecs;
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
offset = ((currentStart - startSecs) / dayLength);
|
||||
if (offset >= [blocks count])
|
||||
[self errorWithFormat: @"event '%@' has a computed offset that"
|
||||
@" overflows the amount of blocks (skipped)",
|
||||
[event objectAtIndex: eventNameIndex]];
|
||||
else
|
||||
{
|
||||
eventEnd = [[event objectAtIndex: eventEndDateIndex] intValue];
|
||||
if (eventEnd < 0)
|
||||
[self errorWithFormat: @"event '%@' has negative end: %d (skipped)",
|
||||
[event objectAtIndex: eventNameIndex], eventEnd];
|
||||
else
|
||||
currentDay = [blocks objectAtIndex: offset];
|
||||
currentDayStart = startSecs + dayLength * offset;
|
||||
|
||||
if (eventEnd > endsSecs)
|
||||
eventEnd = endsSecs;
|
||||
|
||||
if (eventEnd < startSecs)
|
||||
// The event doesn't end in the covered period.
|
||||
// This special case occurs with a DST change.
|
||||
return;
|
||||
|
||||
userState = _userStateInEvent(event);
|
||||
while (currentDayStart + dayLength < eventEnd)
|
||||
{
|
||||
if (eventEnd < eventStart)
|
||||
{
|
||||
swap = eventStart;
|
||||
eventStart = eventEnd;
|
||||
eventEnd = swap;
|
||||
[self warnWithFormat: @"event '%@' has end < start: %d < %d",
|
||||
[event objectAtIndex: eventNameIndex], eventEnd, eventStart];
|
||||
}
|
||||
|
||||
startSecs = (unsigned int) [startDate timeIntervalSince1970];
|
||||
endsSecs = (unsigned int) [endDate timeIntervalSince1970];
|
||||
|
||||
if ([[event objectAtIndex: eventIsCycleIndex] boolValue])
|
||||
recurrenceTime = [[event objectAtIndex: eventRecurrenceIdIndex] unsignedIntValue];
|
||||
else
|
||||
recurrenceTime = 0;
|
||||
|
||||
currentStart = eventStart;
|
||||
if (currentStart < startSecs)
|
||||
{
|
||||
currentStart = startSecs;
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
offset = ((currentStart - startSecs) / dayLength);
|
||||
if (offset >= [blocks count])
|
||||
[self errorWithFormat: @"event '%@' has a computed offset that"
|
||||
@" overflows the amount of blocks (skipped)",
|
||||
[event objectAtIndex: eventNameIndex]];
|
||||
else
|
||||
{
|
||||
currentDay = [blocks objectAtIndex: offset];
|
||||
currentDayStart = startSecs + dayLength * offset;
|
||||
|
||||
if (eventEnd > endsSecs)
|
||||
eventEnd = endsSecs;
|
||||
|
||||
if (eventEnd < startSecs)
|
||||
// The event doesn't end in the covered period.
|
||||
// This special case occurs with a DST change.
|
||||
return;
|
||||
|
||||
userState = _userStateInEvent(event);
|
||||
while (currentDayStart + dayLength < eventEnd)
|
||||
{
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
end: currentDayStart + dayLength - 1
|
||||
number: number
|
||||
onDay: currentDayStart
|
||||
recurrenceTime: recurrenceTime
|
||||
userState: userState];
|
||||
[currentDay addObject: eventBlock];
|
||||
currentDayStart += dayLength;
|
||||
currentStart = currentDayStart;
|
||||
offset++;
|
||||
currentDay = [blocks objectAtIndex: offset];
|
||||
}
|
||||
|
||||
computedEventEnd = eventEnd;
|
||||
|
||||
// We add 5 mins to the end date of an event if the end date
|
||||
// is equal or smaller than the event's start date.
|
||||
if (eventEnd <= currentStart)
|
||||
computedEventEnd = currentStart + (5*60);
|
||||
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
end: computedEventEnd
|
||||
number: number
|
||||
onDay: currentDayStart
|
||||
recurrenceTime: recurrenceTime
|
||||
userState: userState];
|
||||
[currentDay addObject: eventBlock];
|
||||
}
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
end: currentDayStart + dayLength - 1
|
||||
number: number
|
||||
onDay: currentDayStart
|
||||
recurrenceTime: recurrenceTime
|
||||
userState: userState];
|
||||
[currentDay addObject: eventBlock];
|
||||
currentDayStart += dayLength;
|
||||
currentStart = currentDayStart;
|
||||
offset++;
|
||||
currentDay = [blocks objectAtIndex: offset];
|
||||
}
|
||||
|
||||
computedEventEnd = eventEnd;
|
||||
|
||||
// We add 5 mins to the end date of an event if the end date
|
||||
// is equal or smaller than the event's start date.
|
||||
if (eventEnd <= currentStart)
|
||||
computedEventEnd = currentStart + (5*60);
|
||||
|
||||
eventBlock = [self _eventBlockWithStart: currentStart
|
||||
end: computedEventEnd
|
||||
number: number
|
||||
onDay: currentDayStart
|
||||
recurrenceTime: recurrenceTime
|
||||
userState: userState];
|
||||
[currentDay addObject: eventBlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user