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:
@@ -5,6 +5,7 @@
|
||||
package icssub
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -14,6 +15,8 @@ import (
|
||||
"time"
|
||||
|
||||
ical "github.com/emersion/go-ical"
|
||||
|
||||
"github.com/yourusername/caldav-server/internal/icalfix"
|
||||
)
|
||||
|
||||
// DefaultTTL is how long a fetched calendar is cached before being
|
||||
@@ -103,7 +106,14 @@ func (c *Cache) fetch(rawURL string) (*ical.Calendar, error) {
|
||||
return nil, fmt.Errorf("fetching calendar: unexpected status %s", resp.Status)
|
||||
}
|
||||
|
||||
cal, err := ical.NewDecoder(io.LimitReader(resp.Body, maxBodySize)).Decode()
|
||||
body, err := io.ReadAll(io.LimitReader(resp.Body, maxBodySize))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading calendar: %w", err)
|
||||
}
|
||||
// Some remote feeds (Outlook/Exchange-backed ones especially) use
|
||||
// Windows timezone names instead of IANA ones, which go-ical can't
|
||||
// resolve — fix those up before decoding (see internal/icalfix).
|
||||
cal, err := ical.NewDecoder(bytes.NewReader(icalfix.NormalizeTimeZones(body))).Decode()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing calendar: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user