Fix 500 on REPORT for recurring events with Windows timezone IDs
DAVx5 reported a 500 Internal Server Error on a time-range REPORT against a calendar containing a recurring event whose DTSTART/DTEND used a Windows-style TZID (e.g. "W. Europe Standard Time", as commonly written by Outlook/Exchange and some Thunderbird/Lightning setups) instead of an IANA zone name. go-ical resolves TZID via a plain time.LoadLocation call, which only understands IANA names. A simple decode of such an event succeeds (RRULE dates aren't parsed eagerly), but expanding its recurrence - which go-webdav's caldav.Filter does for every time-range REPORT - calls Component.RecurrenceSet, which does call time.LoadLocation(tzid) and fails with "ical: error parsing start time: unknown time zone ...". Add internal/icalfix, a small shared helper that rewrites recognized Windows timezone identifiers (TZID parameters and VTIMEZONE TZID: lines) to their IANA equivalent in raw ICS bytes before decoding. Wire it into every ical.NewDecoder call site: internal/caldav/backend.go's decodeObject (fixes the reported bug), internal/web/calendar.go's event rendering/ICS import, and internal/icssub's remote feed fetching, so a subscribed feed with the same issue doesn't hit it either. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
ical "github.com/emersion/go-ical"
|
||||
"github.com/yourusername/caldav-server/internal/birthdays"
|
||||
"github.com/yourusername/caldav-server/internal/db"
|
||||
"github.com/yourusername/caldav-server/internal/icalfix"
|
||||
"github.com/yourusername/caldav-server/internal/web/templates"
|
||||
)
|
||||
|
||||
@@ -675,7 +676,7 @@ func (s *Server) saveEventFromForm(w http.ResponseWriter, r *http.Request, owner
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
existing, err := ical.NewDecoder(strings.NewReader(string(data))).Decode()
|
||||
existing, err := ical.NewDecoder(bytes.NewReader(icalfix.NormalizeTimeZones(data))).Decode()
|
||||
if err != nil {
|
||||
s.logger.Error("decoding existing event", "error", err)
|
||||
http.Error(w, "internal error", http.StatusInternalServerError)
|
||||
@@ -791,7 +792,7 @@ func (s *Server) saveEvent(owner, cal, id string, calendar *ical.Calendar) error
|
||||
// EventFormData shape used both for pre-filling the edit form and for
|
||||
// placing the event on the month grid.
|
||||
func eventFormFromICS(id string, data []byte) (templates.EventFormData, error) {
|
||||
calendar, err := ical.NewDecoder(strings.NewReader(string(data))).Decode()
|
||||
calendar, err := ical.NewDecoder(bytes.NewReader(icalfix.NormalizeTimeZones(data))).Decode()
|
||||
if err != nil {
|
||||
return templates.EventFormData{}, err
|
||||
}
|
||||
@@ -974,7 +975,7 @@ func (s *Server) handleCalendarImport(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
imported := 0
|
||||
dec := ical.NewDecoder(bytes.NewReader(body))
|
||||
dec := ical.NewDecoder(bytes.NewReader(icalfix.NormalizeTimeZones(body)))
|
||||
for {
|
||||
srcCal, err := dec.Decode()
|
||||
if errors.Is(err, io.EOF) {
|
||||
|
||||
Reference in New Issue
Block a user