diff options
Diffstat (limited to 'modules/calendar-sync-recurrence.el')
| -rw-r--r-- | modules/calendar-sync-recurrence.el | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/modules/calendar-sync-recurrence.el b/modules/calendar-sync-recurrence.el index 72576a6f..2689cdd6 100644 --- a/modules/calendar-sync-recurrence.el +++ b/modules/calendar-sync-recurrence.el @@ -193,21 +193,30 @@ Handles both simple values and values with parameters like TZID." (when (and event-str (stringp event-str) (not (string-empty-p event-str))) (let ((exdates '()) (pos 0)) - ;; Find all EXDATE lines + ;; Find all EXDATE lines. One line may carry several comma-separated + ;; datetimes (RFC 5545); split them so each is excluded individually. + ;; Capture the match end BEFORE split-string: its internal matching + ;; clobbers the match data, and reading (match-end 0) afterwards made + ;; pos jump backwards to a comma offset inside the value -- re-matching + ;; the same line forever and growing the list until the OOM killer + ;; intervened (took two agent sessions down on 2026-07-13). (while (string-match "^EXDATE[^:\n]*:\\([^\n]+\\)" event-str pos) - (push (match-string 1 event-str) exdates) - (setq pos (match-end 0))) + (let ((line-end (match-end 0))) + (dolist (val (split-string (match-string 1 event-str) "," t)) + (push val exdates)) + (setq pos line-end))) (nreverse exdates)))) (defun calendar-sync--get-exdate-line (event-str exdate-value) "Find the full EXDATE line containing EXDATE-VALUE from EVENT-STR. Returns the complete line like -`EXDATE;TZID=America/New_York:20260210T130000'. -Returns nil if not found." +`EXDATE;TZID=America/New_York:20260210T130000'. Matches the value anywhere +in the value list, so a comma-separated line's shared TZID reaches every +value on it. Returns nil if not found." (when (and event-str (stringp event-str) exdate-value) - (let ((pattern (format "^\\(EXDATE[^:]*:%s\\)" (regexp-quote exdate-value)))) + (let ((pattern (format "^EXDATE[^:\n]*:[^\n]*%s" (regexp-quote exdate-value)))) (when (string-match pattern event-str) - (match-string 1 event-str))))) + (match-string 0 event-str))))) (defalias 'calendar-sync--parse-exdate #'calendar-sync--parse-ics-datetime "Parse EXDATE value. See `calendar-sync--parse-ics-datetime'.") |
