diff --git a/framework/Icalendar/lib/Horde/Icalendar.php b/framework/Icalendar/lib/Horde/Icalendar.php index 3d809de3cf7..6ed241ac73c 100644 --- a/framework/Icalendar/lib/Horde/Icalendar.php +++ b/framework/Icalendar/lib/Horde/Icalendar.php @@ -1302,8 +1302,13 @@ function($a, $b) { } for ($i = 0, $n = count($change_times); $i < $n - 1; $i++) { + // See Bug: 14153. Some timezone definitions may be such that a + // transition will incorrectly match due to the way we parse the + // 'end' times. There *may* be a more correct way to do this by + // sorting the transitions/handling 'end' values differently. if (($t >= $change_times[$i]['time']) && - ($t < $change_times[$i + 1]['time'])) { + ($t < $change_times[$i + 1]['time']) && + $this->_checkEndDate($t, $change_times[$i + 1])) { return $change_times[$i]['to']; } } @@ -1315,6 +1320,33 @@ function($a, $b) { return false; } + /** + * Utility method to aid in checking the end date of a transition. + * + * @param integer $t The timestamp of the date we are checking. + * @param array $times A transition array. + * + * @return boolean True if $t is before the end date of the transition + * otherwise false. + */ + protected function _checkEndDate($t, $times) + { + if (empty($times['end'])) { + return true; + } + if (strlen($times['end']) == 4) { + $date = @gmmktime(0, 0, 0, 1, 1, $times['end']); + if ($date && $t < $date) { + return true; + } + return false; + } + + if ($t < $times['end']) { + return true; + } + } + /** * Parses a DateTime field and returns a unix timestamp. If the * field cannot be parsed then the original text is returned diff --git a/framework/Icalendar/package.xml b/framework/Icalendar/package.xml index 055e20efb59..ae1a590a606 100644 --- a/framework/Icalendar/package.xml +++ b/framework/Icalendar/package.xml @@ -23,7 +23,7 @@ mrubinsk@horde.org yes - 2015-07-06 + 2015-11-11 2.1.2 2.1.0 @@ -376,6 +376,7 @@ + @@ -597,6 +598,7 @@ + @@ -1199,7 +1201,7 @@ Lots of improvements, bugfixes and support for more fields and members of the iC stable stable - 2015-07-06 + 2015-11-11 LGPL-2.1 * diff --git a/framework/Icalendar/test/Horde/Icalendar/ParseTest.php b/framework/Icalendar/test/Horde/Icalendar/ParseTest.php index 6850915c8bc..2aacef53efe 100644 --- a/framework/Icalendar/test/Horde/Icalendar/ParseTest.php +++ b/framework/Icalendar/test/Horde/Icalendar/ParseTest.php @@ -362,4 +362,16 @@ public function testBug7423() $ical->getComponent(0)->toHash(true) ); } + + public function testBug14153() + { + $ical = new Horde_Icalendar(); + $ical->parsevCalendar(file_get_contents(__DIR__ . '/fixtures/bug14153.ics')); + $params = $ical->getComponent(1)->getAttribute('DTSTART', true); + $tz = $params[0]['TZID']; + $start = $ical->getComponent(1)->getAttribute('DTSTART'); + $dtstart = new Horde_Date($start, $tz); + $this->assertEquals((string)$dtstart, '2015-10-03 15:00:00'); + } + } diff --git a/framework/Icalendar/test/Horde/Icalendar/fixtures/bug14153.ics b/framework/Icalendar/test/Horde/Icalendar/fixtures/bug14153.ics new file mode 100644 index 00000000000..aa55a511417 --- /dev/null +++ b/framework/Icalendar/test/Horde/Icalendar/fixtures/bug14153.ics @@ -0,0 +1,263 @@ +BEGIN:VCALENDAR +VERSION:2.0 +METHOD:REQUEST +X-WR-CALNAME:Agenda de prova.agenda.nobel.1 +PRODID:-//The Horde Project//Horde iCalendar Library//EN +BEGIN:VEVENT +DTSTART;TZID=Europe/Madrid:20151003T150000 +DTEND;TZID=Europe/Madrid:20151003T160000 +DTSTAMP:20151104T100037Z +UID:20151104110037.BA1yz6O5E9xKjehERqWj1Ha@correudes.upc.edu +CREATED:20151104T100037Z +LAST-MODIFIED:20151104T100037Z +SUMMARY:Prueba bug 13: + nobel.1 invitación semanal a nobel1.1. Inicio: + 3/10/2015 15:00 Fin: 31/10/2015 +ORGANIZER;CN=prova.agenda.nobel.1:mailto:prova.agenda.nobel.1@upc.edu +CLASS:PUBLIC +STATUS:CONFIRMED +TRANSP:OPAQUE +ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:prova. + agenda.nobel1.1@upc.edu +ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:mailto:prova. + agenda.nobel.1@upc.edu +RRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=SA;UNTIL=20151031T225959Z +END:VEVENT +BEGIN:VTIMEZONE +TZID:Europe/Madrid +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +DTSTART:19170505T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +TZNAME:WE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +DTSTART:19180415T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19190405T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19240416T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +DTSTART:19241004T230000 +TZNAME:WE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +DTSTART:19260417T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +DTSTART:19261002T230000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SA;UNTIL=19291006T230000Z +TZNAME:WE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +DTSTART:19270409T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19280414T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19290420T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19370522T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +DTSTART:19371002T230000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SA;UNTIL=19391001T220000Z +TZNAME:WE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0000 +TZOFFSETTO:+0100 +DTSTART:19380322T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19390415T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19400316T230000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19420502T220000 +TZNAME:WEMT +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19420901T220000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19430417T220000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=13,14,15,16,17,18,19;BYDAY=1SA;UNTIL + =19460414T200000Z +TZNAME:WEMT +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19431003T220000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19441010T220000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0100 +DTSTART:19450930T010000 +TZNAME:WEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0100 +TZOFFSETTO:+0000 +DTSTART:19460930T000000 +TZNAME:WE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0300 +DTSTART:19460413T220000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=13,14,15,16,17,18,19;BYDAY=1SA;UNTIL + =19460414T200000Z +TZNAME:CEMT +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0300 +TZOFFSETTO:+0100 +DTSTART:19460930T000000 +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19490430T230000 +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19490930T010000 +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19740413T230000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYMONTHDAY=13,14,15,16,17,18,19;BYDAY=1SA;UNTIL + =19750413T220000Z +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19741006T010000 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=1SU;UNTIL=19751005T000000Z +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19760327T230000 +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19760926T010000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=9;UNTIL=19770925T000000Z +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19781001T010000 +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19790401T010000 +RRULE:FREQ=YEARLY;BYMONTH=4;BYDAY=1SU;UNTIL=19800406T000000Z +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19790930T010000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=9;UNTIL=19950923T230000Z +TZNAME:CE-T +END:STANDARD +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +TZOFFSETTO:+0200 +DTSTART:19810329T010000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3 +TZNAME:CEST +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +TZOFFSETTO:+0100 +DTSTART:19961027T010000 +RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 +TZNAME:CE-T +END:STANDARD +END:VTIMEZONE +END:VCALENDAR