Skip to content

Endless loop in RRuleIterator if BYMONTHDAY does not exist in BYMONTH #329

@PHPGangsta

Description

@PHPGangsta

I'm using vobject 4.1.0

I have the following file:

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//something//DE
CALSCALE:GREGORIAN
X-WR-TIMEZONE:Europe/Berlin
BEGIN:VEVENT
UID:20160103T123422CET-9863LIMv8E
DTSTAMP:20160103T113422Z
DESCRIPTION:important date
DTSTART;TZID=Europe/Berlin:20151231T000000
DTEND;TZID=Europe/Berlin:20151231T235900
RRULE:FREQ=YEARLY;COUNT=6;BYMONTHDAY=31;BYMONTH=11
SUMMARY:important date
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR

The problem here is the BYMONTHDAY=31;BYMONTH=11. It's invalid, there is no day 31 in November. But there is no Exception thrown, and my script (in this case the migration17.php script) runs into an endless loop. You can reproduce it if you do the following:

$vObject = \Sabre\VObject\Reader::read($calendarData);
$it = new \Sabre\VObject\Recur\EventIterator($vObject, '20160103T123422CET-9863LIMv8E');

The problem seems to be in line 558:
https://github.com/fruux/sabre-vobject/blob/master/lib/Recur/RRuleIterator.php#L558
$occurrences is always empty, that's why the "while(true)" runs forever. Why is it empty? Because "out of range dates" are skipped in line 825
https://github.com/fruux/sabre-vobject/blob/master/lib/Recur/RRuleIterator.php#L825

I guess that's causing the endless loop.

Not sure how to fix the problem. Maybe the "out of range date" detection should be earlier, before entering the "while(true)" loop (but we need to take care of leap years then)? Or at least stop the loop when $currentYear reaches year 3000 or so?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions