1<?php 2 3namespace Sabre\VObject\Recur\EventIterator; 4 5use 6 DateTime, 7 DateTimeZone, 8 Sabre\VObject\Component\VCalendar, 9 Sabre\VObject\Recur; 10 11class EventIteratorInfiniteLoopProblemTest extends \PHPUnit_Framework_TestCase { 12 13 public function setUp() { 14 15 $this->vcal = new VCalendar(); 16 17 } 18 19 /** 20 * This bug came from a Fruux customer. This would result in a never-ending 21 * request. 22 */ 23 function testFastForwardTooFar() { 24 25 $ev = $this->vcal->createComponent('VEVENT'); 26 $ev->UID = 'foobar'; 27 $ev->DTSTART = '20090420T180000Z'; 28 $ev->RRULE = 'FREQ=WEEKLY;BYDAY=MO;UNTIL=20090704T205959Z;INTERVAL=1'; 29 30 $this->assertFalse($ev->isInTimeRange(new DateTime('2012-01-01 12:00:00'),new DateTime('3000-01-01 00:00:00'))); 31 32 } 33 34 /** 35 * Different bug, also likely an infinite loop. 36 */ 37 function testYearlyByMonthLoop() { 38 39 $ev = $this->vcal->createComponent('VEVENT'); 40 $ev->UID = 'uuid'; 41 $ev->DTSTART = '20120101T154500'; 42 $ev->DTSTART['TZID'] = 'Europe/Berlin'; 43 $ev->RRULE = 'FREQ=YEARLY;INTERVAL=1;UNTIL=20120203T225959Z;BYMONTH=2;BYSETPOS=1;BYDAY=SU,MO,TU,WE,TH,FR,SA'; 44 $ev->DTEND = '20120101T164500'; 45 $ev->DTEND['TZID'] = 'Europe/Berlin'; 46 47 // This recurrence rule by itself is a yearly rule that should happen 48 // every february. 49 // 50 // The BYDAY part expands this to every day of the month, but the 51 // BYSETPOS limits this to only the 1st day of the month. Very crazy 52 // way to specify this, and could have certainly been a lot easier. 53 $this->vcal->add($ev); 54 55 $it = new Recur\EventIterator($this->vcal,'uuid'); 56 $it->fastForward(new DateTime('2012-01-29 23:00:00', new DateTimeZone('UTC'))); 57 58 $collect = array(); 59 60 while($it->valid()) { 61 $collect[] = $it->getDTSTART(); 62 if ($it->getDTSTART() > new DateTime('2013-02-05 22:59:59', new DateTimeZone('UTC'))) { 63 break; 64 } 65 $it->next(); 66 67 } 68 69 $this->assertEquals( 70 array(new DateTime('2012-02-01 15:45:00', new DateTimeZone('Europe/Berlin'))), 71 $collect 72 ); 73 74 } 75 76 /** 77 * Something, somewhere produced an ics with an interval set to 0. Because 78 * this means we increase the current day (or week, month) by 0, this also 79 * results in an infinite loop. 80 * 81 * @expectedException InvalidArgumentException 82 * @return void 83 */ 84 function testZeroInterval() { 85 86 $ev = $this->vcal->createComponent('VEVENT'); 87 $ev->UID = 'uuid'; 88 $ev->DTSTART = '20120824T145700Z'; 89 $ev->RRULE = 'FREQ=YEARLY;INTERVAL=0'; 90 $this->vcal->add($ev); 91 92 $it = new Recur\EventIterator($this->vcal,'uuid'); 93 $it->fastForward(new DateTime('2013-01-01 23:00:00', new DateTimeZone('UTC'))); 94 95 // if we got this far.. it means we are no longer infinitely looping 96 97 } 98 99} 100