From 5b5b542f2f98e3113b06dcfc6de60103734362c6 Mon Sep 17 00:00:00 2001 From: Conrad Hoffmann Date: Thu, 1 Feb 2024 14:05:49 +0100 Subject: [PATCH] caldav: fix match on open time ranges Matches on open time ranges (i.e. no end date) were not properly handled, as `end` is simply the zero time, which confuses the `.Before()` and `.After()` logic employed here. This commit fixes that by adding the appropriate `.IsZero()` checks and also adds a test case. The current behavior unfortunately broke compatibility with DAVx5, which by default queries only events less than 90 days ago (by using an open time range). --- caldav/match.go | 11 ++++------- caldav/match_test.go | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/caldav/match.go b/caldav/match.go index 948b33c..459a663 100644 --- a/caldav/match.go +++ b/caldav/match.go @@ -138,7 +138,6 @@ func matchCompTimeRange(start, end time.Time, comp *ical.Component) (bool, error return len(rset.Between(start, end, true)) > 0, nil } - // TODO handle "infinity" values in query // TODO handle more than just events if comp.Name != ical.CompEvent { return false, nil @@ -155,15 +154,15 @@ func matchCompTimeRange(start, end time.Time, comp *ical.Component) (bool, error } // Event starts in time range - if eventStart.After(start) && eventStart.Before(end) { + if eventStart.After(start) && (end.IsZero() || eventStart.Before(end)) { return true, nil } // Event ends in time range - if eventEnd.After(start) && eventEnd.Before(end) { + if eventEnd.After(start) && (end.IsZero() || eventEnd.Before(end)) { return true, nil } // Event covers entire time range plus some - if eventStart.Before(start) && eventEnd.After(end) { + if eventStart.Before(start) && (!end.IsZero() && eventEnd.After(end)) { return true, nil } return false, nil @@ -172,13 +171,11 @@ func matchCompTimeRange(start, end time.Time, comp *ical.Component) (bool, error func matchPropTimeRange(start, end time.Time, field *ical.Prop) (bool, error) { // See https://datatracker.ietf.org/doc/html/rfc4791#section-9.9 - // TODO handle "infinity" values in query - ptime, err := field.DateTime(start.Location()) if err != nil { return false, err } - if ptime.After(start) && ptime.Before(end) { + if ptime.After(start) && (end.IsZero() || ptime.Before(end)) { return true, nil } return false, nil diff --git a/caldav/match_test.go b/caldav/match_test.go index 73114bb..79e5095 100644 --- a/caldav/match_test.go +++ b/caldav/match_test.go @@ -209,6 +209,23 @@ END:VCALENDAR`) addrs: []CalendarObject{event1, event2, event3, todo1}, want: []CalendarObject{event2, event3}, }, + { + // https://datatracker.ietf.org/doc/html/rfc4791#section-7.8.1 + name: "events in open time range (no end date)", + query: &CalendarQuery{ + CompFilter: CompFilter{ + Name: "VCALENDAR", + Comps: []CompFilter{ + CompFilter{ + Name: "VEVENT", + Start: toDate(t, "20060104T000000Z"), + }, + }, + }, + }, + addrs: []CalendarObject{event1, event2, event3, todo1}, + want: []CalendarObject{event2, event3}, + }, { // https://datatracker.ietf.org/doc/html/rfc4791#section-7.8.6 name: "events by UID",