diff --git a/lib/Recur/RRuleIterator.php b/lib/Recur/RRuleIterator.php index 402e2de83..fecb9b298 100644 --- a/lib/Recur/RRuleIterator.php +++ b/lib/Recur/RRuleIterator.php @@ -588,6 +588,11 @@ protected function nextYearly() { (int)$currentDayOfMonth ); + // maximum year 10000 should be safe to stop (2016 + max 3500 yearly occurrences) + if ((int)$currentYear > 10000) { + throw new NoInstancesException('This recurrence rule does not generate any valid instances, stopped in year 10000'); + } + } // If we made it here, it means we got a valid occurrence diff --git a/tests/VObject/Recur/RRuleIteratorTest.php b/tests/VObject/Recur/RRuleIteratorTest.php index 24efef907..fa9532e2e 100644 --- a/tests/VObject/Recur/RRuleIteratorTest.php +++ b/tests/VObject/Recur/RRuleIteratorTest.php @@ -275,7 +275,7 @@ function testMonthly() { } - function testMonlthyEndOfMonth() { + function testMonthlyEndOfMonth() { $this->parse( 'FREQ=MONTHLY;INTERVAL=2;COUNT=12', @@ -458,6 +458,36 @@ function testYearlyByMonthByDay() { } + /** + * There is no November 31st, the endless loop should be stopped by an Exception + * + * @expectedException \Sabre\VObject\Recur\NoInstancesException + */ + function testYearlyByMonthByMonthDayNotExistingDay() { + + $this->parse( + 'FREQ=YEARLY;COUNT=6;BYMONTH=11;BYMONTHDAY=31', + '2011-04-04 00:00:00', + [] + ); + + } + + /** + * There is no February 29th in odd years, the endless loop should be stopped by an Exception + * + * @expectedException \Sabre\VObject\Recur\NoInstancesException + */ + function testYearlyLeapYearsInOddYears() { + + $this->parse( + 'FREQ=YEARLY;INTERVAL=2;COUNT=6;BYMONTH=2;BYMONTHDAY=29', + '2011-02-29 00:00:00', + [] + ); + + } + function testFastForward() { // The idea is that we're fast-forwarding too far in the future, so