Revision: 3620 http://trac.macosforge.org/projects/calendarserver/changeset/3620 Author: cdaboo@apple.com Date: 2009-01-28 15:17:49 -0800 (Wed, 28 Jan 2009) Log Message: ----------- Reject invalid recurrence components. Modified Paths: -------------- CalendarServer/trunk/run CalendarServer/trunk/twistedcaldav/ical.py Modified: CalendarServer/trunk/run =================================================================== --- CalendarServer/trunk/run 2009-01-28 23:16:21 UTC (rev 3619) +++ CalendarServer/trunk/run 2009-01-28 23:17:49 UTC (rev 3620) @@ -692,7 +692,7 @@ caldavtester="${top}/CalDAVTester"; -svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 3608; +svn_get "CalDAVTester" "${caldavtester}" "${svn_uri_base}/CalDAVTester/trunk" 3619; # # Calendar Server Modified: CalendarServer/trunk/twistedcaldav/ical.py =================================================================== --- CalendarServer/trunk/twistedcaldav/ical.py 2009-01-28 23:16:21 UTC (rev 3619) +++ CalendarServer/trunk/twistedcaldav/ical.py 2009-01-28 23:17:49 UTC (rev 3620) @@ -1042,12 +1042,14 @@ # Must not contain more than one type of iCalendar component, except for # the required timezone components, and component UIDs must match # - ctype = None - component_id = None - component_rids = set() - timezone_refs = set() - timezones = set() - got_master = False + ctype = None + component_id = None + component_rids = set() + timezone_refs = set() + timezones = set() + got_master = False + got_override = False + master_recurring = False for subcomponent in self.subcomponents(): # Disallowed in CalDAV-Access-08, section 4.1 @@ -1070,21 +1072,32 @@ uid = subcomponent.propertyValue("UID") if uid is None: raise ValueError("All components must have UIDs") - + rid = subcomponent.getRecurrenceIDUTC() + + # Verify that UIDs are the same if component_id is None: component_id = uid - else: - if component_id != uid: + elif component_id != uid: raise ValueError("Calendar resources may not contain components with different UIDs " + "(%s and %s found)" % (component_id, subcomponent.propertyValue("UID"))) - elif subcomponent.propertyValue("Recurrence-ID") is None: - if got_master: - raise ValueError("Calendar resources may not contain components with the same UIDs and no Recurrence-IDs " + - "(%s and %s found)" % (component_id, subcomponent.propertyValue("UID"))) - else: - got_master = True - - rid = subcomponent.getRecurrenceIDUTC() + + # Verify that there is only one master component + if rid is None: + if got_master: + raise ValueError("Calendar resources may not contain components with the same UIDs and no Recurrence-IDs " + + "(%s and %s found)" % (component_id, subcomponent.propertyValue("UID"))) + else: + got_master = True + master_recurring = subcomponent.hasProperty("RRULE") or subcomponent.hasProperty("RDATE") + else: + got_override = True + + # Check that if an override is present then the master is recurring + if got_override and got_master and not master_recurring: + raise ValueError("Calendar resources must have a recurring master component if there is an overridden one " + + "(%s)" % (subcomponent.propertyValue("UID"),)) + + # Check for duplicate RECURRENCE-IDs if rid in component_rids: raise ValueError("Calendar resources may not contain components with the same Recurrence-IDs " + "(%s)" % (rid,))