diff --git a/ChangeLog b/ChangeLog index 94fba7737..65907e7c1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-01-05 Francis Lachapelle + + * SoObjects/SOGo/SOGoUserManager.m (-_registerSource:inDomain::): + log error when duplicated IDs are found. + 2012-01-04 Wolfgang Sourdeau * UI/WebServerResources/ContactsUI.js @@ -66,6 +71,20 @@ the identifier of the source that authenticated the specified user as the "SOGoSource" entry of the returned dictionary. +2012-01-03 Francis Lachapelle + + * SoObjects/Appointments/SOGoAptMailNotification.m (-setupValues): + don't set the start/end times when dealing with an all-day event. + + * SoObjects/Appointments/SOGoAptMailInvitation.m (-getBody): don't + display the start/end times when dealing with an all-day event. + + * SoObjects/Appointments/SOGoAptMailReceipt.m (-_formattedUserDate:): idem. + + * SoObjects/Appointments/SOGoAptMailUpdate.m (-getSubject): idem. + + * SoObjects/Appointments/SOGoAptMailDeletion.m (-getBody): idem. + 2012-01-02 Francis Lachapelle * UI/WebServerResources/UIxPreferences.js (getFilterFromEditor): diff --git a/SOPE/NGCards/ChangeLog b/SOPE/NGCards/ChangeLog index 8c8fe0b52..1a10be126 100644 --- a/SOPE/NGCards/ChangeLog +++ b/SOPE/NGCards/ChangeLog @@ -1,3 +1,8 @@ +2012-01-09 Wolfgang Sourdeau + + * NSString+NGCards.m (-vCardSubvalues): fixed allocation of + parsing buffer to avoid a buffer overflow. + 2011-12-30 Wolfgang Sourdeau * NGVCard.m (-initWithUid:): initialize "CLASS" and "PROFILE". diff --git a/SOPE/NGCards/NSString+NGCards.m b/SOPE/NGCards/NSString+NGCards.m index e46b2e29d..1c1e1fe66 100644 --- a/SOPE/NGCards/NSString+NGCards.m +++ b/SOPE/NGCards/NSString+NGCards.m @@ -325,7 +325,7 @@ ELEM;...:subvalue1;subvalue1,subvalue2 (where KEY = @"") */ NSMutableDictionary *values; /* key <> ordered values associations */ NSMutableArray *orderedValues = nil; /* those are separated by ';' and contain - subvalues, may or may not be named */ + subvalues, may or may not be named */ NSMutableArray *subValues = nil; /* those are separeted by ',' */ unichar *stringBuffer, *substringBuffer; NSString *valuesKey, *substring; @@ -337,7 +337,7 @@ valuesKey = @""; max = [self length]; - stringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * max + 1); + stringBuffer = NSZoneMalloc (NULL, sizeof (unichar) * (max + 1)); [self getCharacters: stringBuffer]; stringBuffer[max] = 0; diff --git a/SoObjects/Appointments/English.lproj/Localizable.strings b/SoObjects/Appointments/English.lproj/Localizable.strings index 1f432a7d9..b2cea94aa 100644 --- a/SoObjects/Appointments/English.lproj/Localizable.strings +++ b/SoObjects/Appointments/English.lproj/Localizable.strings @@ -35,14 +35,19 @@ vtodo_class2 = "(Confidential task)"; /* Invitation */ "Event Invitation: \"%{Summary}\"" = "Event Invitation: \"%{Summary}\""; "(sent by %{SentBy}) " = "(sent by %{SentBy}) "; +"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" = "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"; "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"; /* Deletion */ "Event Cancelled: \"%{Summary}\"" = "Event Cancelled: \"%{Summary}\""; +"%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}" += "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate}\nEnd: %{EndDate}\nDescription: %{Description}"; "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" = "%{Organizer} %{SentByText}has cancelled this event: %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}"; /* Update */ +"The appointment \"%{Summary}\" for the %{OldStartDate} has changed" += "The appointment \"%{Summary}\" for the %{OldStartDate} has changed"; "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed" = "The appointment \"%{Summary}\" for the %{OldStartDate} at %{OldStartTime} has changed"; "The following parameters have changed in the \"%{Summary}\" meeting:" diff --git a/SoObjects/Appointments/SOGoAptMailDeletion.m b/SoObjects/Appointments/SOGoAptMailDeletion.m index 5db61e955..987a8fece 100644 --- a/SoObjects/Appointments/SOGoAptMailDeletion.m +++ b/SoObjects/Appointments/SOGoAptMailDeletion.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Inverse + Copyright (C) 2010-2012 Inverse This file is part of SOGo @@ -49,12 +49,20 @@ if (!values) [self setupValues]; - bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled" - @" this event: %{Summary}.\n\n" - @"Start: %{StartDate} at %{StartTime}\n" - @"End: %{EndDate} at %{EndTime}\n" - @"Description: %{Description}") - inContext: context]; + if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) + bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled" + @" this event: %{Summary}.\n\n" + @"Start: %{StartDate} at %{StartTime}\n" + @"End: %{EndDate} at %{EndTime}\n" + @"Description: %{Description}") + inContext: context]; + else + bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has cancelled" + @" this event: %{Summary}.\n\n" + @"Start: %{StartDate}\n" + @"End: %{EndDate}\n" + @"Description: %{Description}") + inContext: context]; return [values keysWithFormat: bodyFormat]; } diff --git a/SoObjects/Appointments/SOGoAptMailInvitation.m b/SoObjects/Appointments/SOGoAptMailInvitation.m index d33d332f4..09be772ce 100644 --- a/SoObjects/Appointments/SOGoAptMailInvitation.m +++ b/SoObjects/Appointments/SOGoAptMailInvitation.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Inverse + Copyright (C) 2010-2012 Inverse This file is part of SOGo @@ -54,8 +54,20 @@ if (!values) [self setupValues]; - bodyFormat = [self labelForKey: @"%{Organizer} %{SentByText}has invited you to %{Summary}.\n\nStart: %{StartDate} at %{StartTime}\nEnd: %{EndDate} at %{EndTime}\nDescription: %{Description}" - inContext: context]; + if ([values objectForKey: @"StartTime"] && [values objectForKey: @"EndTime"]) + bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you" + @" to %{Summary}.\n\n" + @"Start: %{StartDate} at %{StartTime}\n" + @"End: %{EndDate} at %{EndTime}\n" + @"Description: %{Description}") + inContext: context]; + else + bodyFormat = [self labelForKey: (@"%{Organizer} %{SentByText}has invited you" + @" to %{Summary}.\n\n" + @"Start: %{StartDate}\n" + @"End: %{EndDate}\n" + @"Description: %{Description}") + inContext: context]; return [values keysWithFormat: bodyFormat]; } diff --git a/SoObjects/Appointments/SOGoAptMailNotification.m b/SoObjects/Appointments/SOGoAptMailNotification.m index 85f2e6b39..70f911592 100644 --- a/SoObjects/Appointments/SOGoAptMailNotification.m +++ b/SoObjects/Appointments/SOGoAptMailNotification.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2006-2010 Inverse inc. + Copyright (C) 2006-2012 Inverse inc. Copyright (C) 2000-2005 SKYRIX Software AG This file is part of SOGo. @@ -209,14 +209,16 @@ date = [self newStartDate]; [values setObject: [dateFormatter shortFormattedDate: date] forKey: @"StartDate"]; - [values setObject: [dateFormatter formattedTime: date] - forKey: @"StartTime"]; + if (![apt isAllDay]) + [values setObject: [dateFormatter formattedTime: date] + forKey: @"StartTime"]; date = [self newEndDate]; [values setObject: [dateFormatter shortFormattedDate: date] forKey: @"EndDate"]; - [values setObject: [dateFormatter formattedTime: date] - forKey: @"EndTime"]; + if (![apt isAllDay]) + [values setObject: [dateFormatter formattedTime: date] + forKey: @"EndTime"]; description = [[self apt] comment]; [values setObject: (description ? description : @"") diff --git a/SoObjects/Appointments/SOGoAptMailReceipt.m b/SoObjects/Appointments/SOGoAptMailReceipt.m index 3d844008e..6a6c70bfb 100644 --- a/SoObjects/Appointments/SOGoAptMailReceipt.m +++ b/SoObjects/Appointments/SOGoAptMailReceipt.m @@ -1,6 +1,6 @@ /* SOGoAptMailReceipt.m - this file is part of SOGo * - * Copyright (C) 2009 Inverse inc. + * Copyright (C) 2009-2012 Inverse inc. * * Author: Wolfgang Sourdeau * @@ -146,9 +146,12 @@ static NSCharacterSet *wsSet = nil; formatter = [currentUser dateFormatterInContext: context]; - return [NSString stringWithFormat: @"%@ - %@", - [formatter formattedDate: tzDate], - [formatter formattedTime: tzDate]]; + if ([apt isAllDay]) + return [formatter formattedDate: tzDate]; + else + return [NSString stringWithFormat: @"%@ - %@", + [formatter formattedDate: tzDate], + [formatter formattedTime: tzDate]]; } - (NSString *) aptStartDate diff --git a/SoObjects/Appointments/SOGoAptMailUpdate.m b/SoObjects/Appointments/SOGoAptMailUpdate.m index c6ef1f062..5b413e38b 100644 --- a/SoObjects/Appointments/SOGoAptMailUpdate.m +++ b/SoObjects/Appointments/SOGoAptMailUpdate.m @@ -1,5 +1,5 @@ /* - Copyright (C) 2010 Inverse + Copyright (C) 2010-2012 Inverse This file is part of SOGo @@ -131,8 +131,10 @@ date = [self oldStartDate]; [values setObject: [dateFormatter shortFormattedDate: date] forKey: @"OldStartDate"]; - [values setObject: [dateFormatter formattedTime: date] - forKey: @"OldStartTime"]; + + if (![apt isAllDay]) + [values setObject: [dateFormatter formattedTime: date] + forKey: @"OldStartTime"]; [self _setupBodyValuesWithFormatter: dateFormatter]; } @@ -144,10 +146,16 @@ if (!values) [self setupValues]; - subjectFormat = [self labelForKey: @"The appointment \"%{Summary}\" for the" - @" %{OldStartDate} at" - @" %{OldStartTime} has changed" - inContext: context]; + if ([values objectForKey: @"OldStartTime"]) + subjectFormat = [self labelForKey: (@"The appointment \"%{Summary}\" for the" + @" %{OldStartDate} at" + @" %{OldStartTime} has changed") + inContext: context]; + else + subjectFormat = [self labelForKey: (@"The appointment \"%{Summary}\" for the" + @" %{OldStartDate}" + @" has changed") + inContext: context]; return [values keysWithFormat: subjectFormat]; } diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 336585ba6..f4d60fdfa 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -103,44 +103,51 @@ sourceID = [udSource objectForKey: @"id"]; if ([sourceID length] > 0) { - type = [[udSource objectForKey: @"type"] lowercaseString]; - c = NSClassFromString([_registry sourceClassForType: type]); - sogoSource = [c sourceFromUDSource: udSource inDomain: domain]; - if (sourceID) - [_sources setObject: sogoSource forKey: sourceID]; - else - [self errorWithFormat: @"id field missing in an user source," - @" check the SOGoUserSources defaults"]; - metadata = [NSMutableDictionary dictionary]; - if (domain) - [metadata setObject: domain forKey: @"domain"]; - value = [udSource objectForKey: @"canAuthenticate"]; - if (value) - [metadata setObject: value forKey: @"canAuthenticate"]; - value = [udSource objectForKey: @"isAddressBook"]; - if (value) - { - [metadata setObject: value forKey: @"isAddressBook"]; - isAddressBook = [value boolValue]; - } - else - isAddressBook = NO; - value = [udSource objectForKey: @"displayName"]; - if (value) - [metadata setObject: value forKey: @"displayName"]; + if ([_sourcesMetadata objectForKey: sourceID]) + [self errorWithFormat: @"attempted to register a contact/user source" + @" with duplicated id (%@)", sourceID]; else { - if (isAddressBook) - [self errorWithFormat: @"addressbook source '%@' has" - @" no displayname", sourceID]; + type = [[udSource objectForKey: @"type"] lowercaseString]; + c = NSClassFromString([_registry sourceClassForType: type]); + sogoSource = [c sourceFromUDSource: udSource inDomain: domain]; + if (sourceID) + [_sources setObject: sogoSource forKey: sourceID]; + else + [self errorWithFormat: @"id field missing in an user source," + @" check the SOGoUserSources defaults"]; + metadata = [NSMutableDictionary dictionary]; + if (domain) + [metadata setObject: domain forKey: @"domain"]; + value = [udSource objectForKey: @"canAuthenticate"]; + if (value) + [metadata setObject: value forKey: @"canAuthenticate"]; + value = [udSource objectForKey: @"isAddressBook"]; + if (value) + { + [metadata setObject: value forKey: @"isAddressBook"]; + isAddressBook = [value boolValue]; + } + else + isAddressBook = NO; + value = [udSource objectForKey: @"displayName"]; + if (value) + [metadata setObject: value forKey: @"displayName"]; + else + { + if (isAddressBook) + [self errorWithFormat: @"addressbook source '%@' has" + @" no displayname", sourceID]; + } + value = [udSource objectForKey: @"MailFieldNames"]; + if (value) + [metadata setObject: value forKey: @"MailFieldNames"]; + value = [udSource objectForKey: @"SearchFieldNames"]; + if (value) + [metadata setObject: value forKey: @"SearchFieldNames"]; + + [_sourcesMetadata setObject: metadata forKey: sourceID]; } - value = [udSource objectForKey: @"MailFieldNames"]; - if (value) - [metadata setObject: value forKey: @"MailFieldNames"]; - value = [udSource objectForKey: @"SearchFieldNames"]; - if (value) - [metadata setObject: value forKey: @"SearchFieldNames"]; - [_sourcesMetadata setObject: metadata forKey: sourceID]; } else [self errorWithFormat: @"attempted to register a contact/user source" diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 670ae5a8c..bcac3cdfa 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -457,7 +457,7 @@ { WOResponse *result; NSDictionary *data; - NSCalendarDate *eventDate; + NSCalendarDate *eventStartDate, *eventEndDate; NSTimeZone *timeZone; SOGoUserDefaults *ud; SOGoCalendarComponent *co; @@ -469,8 +469,10 @@ result = [self responseWithStatus: 200]; ud = [[context activeUser] userDefaults]; timeZone = [ud timeZone]; - eventDate = [event startDate]; - [eventDate setTimeZone: timeZone]; + eventStartDate = [event startDate]; + eventEndDate = [event endDate]; + [eventStartDate setTimeZone: timeZone]; + [eventEndDate setTimeZone: timeZone]; co = [self clientObject]; if (!componentCalendar) @@ -507,8 +509,10 @@ data = [NSDictionary dictionaryWithObjectsAndKeys: [componentCalendar displayName], @"calendar", [event tag], @"component", - [dateFormatter formattedDate: eventDate], @"startDate", - [dateFormatter formattedTime: eventDate], @"startTime", + [dateFormatter formattedDate: eventStartDate], @"startDate", + [dateFormatter formattedTime: eventStartDate], @"startTime", + [dateFormatter formattedDate: eventEndDate], @"endDate", + [dateFormatter formattedTime: eventEndDate], @"endTime", ([event hasRecurrenceRules] ? @"1": @"0"), @"isRecurring", ([event isAllDay] ? @"1": @"0"), @"isAllDay", [event summary], @"summary",