mirror of
https://github.com/kennethnym/aris.git
synced 2026-03-20 00:51:20 +00:00
Compare commits
2 Commits
ba0450d0aa
...
feat/calda
| Author | SHA1 | Date | |
|---|---|---|---|
|
2717ec1b30
|
|||
|
a4baef521f
|
@@ -14,6 +14,13 @@ export interface ICalTimeRange {
|
||||
end: Date
|
||||
}
|
||||
|
||||
/**
|
||||
* Safety cap to prevent runaway iteration on pathological recurrence rules.
|
||||
* Each iteration is pure date math (no I/O), so a high cap is fine.
|
||||
* 10,000 covers a daily event with DTSTART ~27 years in the past.
|
||||
*/
|
||||
const MAX_RECURRENCE_ITERATIONS = 10_000
|
||||
|
||||
/**
|
||||
* Parses a raw iCalendar string and extracts VEVENT components
|
||||
* into CalDavEventData objects.
|
||||
@@ -106,11 +113,23 @@ export function parseICalEvents(
|
||||
continue
|
||||
}
|
||||
|
||||
// Expand recurring event occurrences within the time range
|
||||
// Expand recurring event occurrences within the time range.
|
||||
// The iterator must start from DTSTART (not rangeStart) because
|
||||
// ical.js needs to walk the recurrence rule grid from the original
|
||||
// anchor. We cap iterations to avoid runaway expansion on
|
||||
// pathological rules.
|
||||
const iter = masterEvent.iterator()
|
||||
let next: InstanceType<typeof ICAL.Time> | null = iter.next()
|
||||
let iterations = 0
|
||||
|
||||
while (next) {
|
||||
if (++iterations > MAX_RECURRENCE_ITERATIONS) {
|
||||
console.warn(
|
||||
`[aris.caldav] Recurrence expansion for "${masterEvent.uid}" hit iteration limit (${MAX_RECURRENCE_ITERATIONS}), stopping`,
|
||||
)
|
||||
break
|
||||
}
|
||||
|
||||
// Stop once we're past the range end
|
||||
if (next.compare(rangeEnd) >= 0) break
|
||||
|
||||
|
||||
Reference in New Issue
Block a user