From 524ae817b3655bae6473e1109f2a426dfd381d19 Mon Sep 17 00:00:00 2001 From: Georg Ehrke Date: Fri, 13 Jan 2017 19:21:17 +0100 Subject: [PATCH] replace TRIGGER:P with TRIGGER:P0D Signed-off-by: Georg Ehrke --- js/app/models/veventModel.js | 27 +++++++-- tests/js/unit/models/veventModelSpec.js | 81 +++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/js/app/models/veventModel.js b/js/app/models/veventModel.js index 24d5038cc3..66222f7594 100644 --- a/js/app/models/veventModel.js +++ b/js/app/models/veventModel.js @@ -284,24 +284,35 @@ app.factory('VEvent', function(TimezoneService, FcEvent, SimpleEvent, ICalFactor * @returns {string} */ VEvent.sanDate = function(ics) { - - // console.log( ICAL.Time.now() ); - ics.split("\n").forEach(function(el, i) { var findTypes = ['DTSTART', 'DTEND']; var dateType = /[^:]*/.exec(el)[0]; var icsDate = null; - if (findTypes.indexOf(dateType) >= 0 && el.trim().substr(-3) === "T::") { // is date without time + if (findTypes.indexOf(dateType) >= 0 && el.trim().substr(-3) === 'T::') { // is date without time icsDate = el.replace(/[^0-9]/g, ''); - ics = ics.replace(el, dateType + ";VALUE=DATE:" + icsDate); + ics = ics.replace(el, dateType + ';VALUE=DATE:' + icsDate); } }); return ics; }; + /** + * fix incorrectly populated trigger + * @param {string} ics + * @returns {string} + */ + VEvent.sanTrigger = function(ics) { + const regex = /^TRIGGER:P$/gm; + if (ics.match(regex)) { + ics = ics.replace(regex, 'TRIGGER:P0D'); + } + + return ics; + }; + /** * create a VEvent object from raw ics data * @param {Calendar} calendar @@ -313,10 +324,14 @@ app.factory('VEvent', function(TimezoneService, FcEvent, SimpleEvent, ICalFactor VEvent.fromRawICS = function(calendar, ics, uri, etag='') { let comp; - if (ics.search("T::") > 0) { // no time + if (ics.search('T::') > 0) { // no time ics = VEvent.sanDate(ics); } + if (ics.search('TRIGGER:P') > 0) { + ics = VEvent.sanTrigger(ics); + } + try { const jCal = ICAL.parse(ics); comp = new ICAL.Component(jCal); diff --git a/tests/js/unit/models/veventModelSpec.js b/tests/js/unit/models/veventModelSpec.js index 238939beef..440d69df5d 100644 --- a/tests/js/unit/models/veventModelSpec.js +++ b/tests/js/unit/models/veventModelSpec.js @@ -429,6 +429,49 @@ DTSTART:19701025T030000 RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 END:STANDARD END:VTIMEZONE +END:VCALENDAR`; + + const ics12 = `BEGIN:VCALENDAR +VERSION:2.0 +CALSCALE:GREGORIAN +PRODID:-//SabreDAV//SabreDAV//EN +X-WR-CALNAME:Test +X-APPLE-CALENDAR-COLOR:#c274e7 +BEGIN:VTIMEZONE +TZID:Europe/Berlin +BEGIN:DAYLIGHT +TZOFFSETFROM:+0100 +RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU +DTSTART:19810329T020000 +TZNAME:GMT+2 +TZOFFSETTO:+0200 +END:DAYLIGHT +BEGIN:STANDARD +TZOFFSETFROM:+0200 +RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU +DTSTART:19961027T030000 +TZNAME:GMT+1 +TZOFFSETTO:+0100 +END:STANDARD +END:VTIMEZONE +BEGIN:VEVENT +CLASS:PUBLIC +DESCRIPTION: +DTEND;TZID=Europe/Berlin:20170105T130000 +DTSTART;TZID=Europe/Berlin:20170105T120000 +DTSTAMP:20170103T150245Z +LAST-MODIFIED:20170103T150246Z +PRIORITY:5 +SEQUENCE:1 +SUMMARY:Test +TRANSP:OPAQUE +UID:348acb0f-b02f-4800-9fde-202a0717c5b5 +BEGIN:VALARM +ACTION:DISPLAY +DESCRIPTION:Reminder +TRIGGER:P +END:VALARM +END:VEVENT END:VCALENDAR`; const timezone_nyc = { @@ -1862,4 +1905,42 @@ END:VCALENDAR`.split("\n").join("\r\n")); expect(vevent.comp).toEqual(root); expect(vevent.uri).toEqual('Nextcloud-123456.ics'); }); + + it ('should correctly sanatize malformed triggers', () => { + const calendar = {this_is_a_fancy_calendar: true}; + const vevent = VEvent.fromRawICS(calendar, ics12); + + let called = false; + + const start = moment('2017-01-01'); + const end = moment('2017-01-31'); + + vevent.getFcEvent(start, end, timezone_berlin).then((fcEvents) => { + expect(fcEvents.length).toEqual(1); + expect(fcEvents[0][1].toString()).toEqual(`BEGIN:VEVENT +CLASS:PUBLIC +DESCRIPTION: +DTEND;TZID=Europe/Berlin:20170105T130000 +DTSTART;TZID=Europe/Berlin:20170105T120000 +DTSTAMP:20170103T150245Z +LAST-MODIFIED:20170103T150246Z +PRIORITY:5 +SEQUENCE:1 +SUMMARY:Test +TRANSP:OPAQUE +UID:348acb0f-b02f-4800-9fde-202a0717c5b5 +BEGIN:VALARM +ACTION:DISPLAY +DESCRIPTION:Reminder +TRIGGER:P0D +END:VALARM +END:VEVENT`.split("\n").join("\r\n")); + + called = true; + }).catch(() => fail('Promise was not supposed to fail')); + + $rootScope.$apply(); + + expect(called).toEqual(true); + }); });