Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
PHPGangsta opened this issue Jul 12, 2016 · 1 comment · May be fixed by #350
Open

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

PHPGangsta opened this issue Jul 12, 2016 · 1 comment · May be fixed by #350

Comments

@PHPGangsta
Copy link
Contributor

PHPGangsta commented Jul 12, 2016

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?

PHPGangsta added a commit to PHPGangsta/sabre-vobject that referenced this issue Jul 14, 2016
evert added a commit that referenced this issue Oct 24, 2016
@evert evert linked a pull request Oct 24, 2016 that will close this issue
EoleDev pushed a commit to EoleDev/vobject that referenced this issue Jul 25, 2018
@willrowe
Copy link

I found another case where the RRULE is not being validated properly. A validation step should probably be added before iterating to ensure that it is actually iterable.

If for whatever reason a frequency isn't provided, it will loop until it hits the limit. As an example, the following RRULE can be passed and iterated without any exceptions until it hits the limit:

BEGIN:VEVENT
RRULE:INTERVAL=1;BYMONTH=8;BYMONTHDAY=8
DTSTART:20220807T210000Z
END:VEVENT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants