InfiniteLoopProblemTest.php 2.9 KB

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