Repository: pimutils/khal
Pull request #1259 (2023-05-25 07:15:11)

Raise error properly on failure to parse ics
If cal_from_ics in icalendar.py raises a ValueError that is not to do with timezone issue, it will raise it instead of ignoring it and then generating "UnboundLocalError: local variable 'cal' referenced before assignment"

geier: Good catch, thanks! Could you please add yourself to AUTHORS.txt, and -- if you have -- provide an example .ics file that triggers the issue? (I'd like to write a test to cover that case.) 

Patch:
diff --git a/AUTHORS.txt b/AUTHORS.txt
index f95ca74..a312f47 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -51,3 +51,4 @@ Henning Ullrich - github {at] henning-ullrich [dot] de
 Jason Cox - me [at] jasoncarloscox [dot] com - https://jasoncarloscox.com
 Michael Tretter - michael.tretter [at] posteo [dot] net
 Raúl Medina - raulmgcontact [at] gmail (dot] com
+Matthew Rademaker - matthew.rademaker [at] gmail [dot] com
diff --git a/khal/icalendar.py b/khal/icalendar.py
index 29fa60c..5ae1787 100644
--- a/khal/icalendar.py
+++ b/khal/icalendar.py
@@ -547,4 +547,6 @@ def cal_from_ics(ics: str) -> icalendar.Calendar:
             icalendar.vUTCOffset.ignore_exceptions = True
             cal = icalendar.Calendar.from_ical(ics)
             icalendar.vUTCOffset.ignore_exceptions = False
+        else:
+            raise
     return cal


Test patch:
diff --git a/tests/cli_test.py b/tests/cli_test.py
index 47bc027..bcd904b 100644
--- a/tests/cli_test.py
+++ b/tests/cli_test.py
@@ -431,6 +431,14 @@ def test_no_default_new(runner):
             "please provide one explicitly.") in result.output
     assert result.exit_code == 2
 
+def test_print_bad_ics(runner):
+    """Attempt to print a .ics that is malformed, but does not have a DST-related error."""
+    runner = runner()
+    result = runner.invoke(main_khal, ['printics', _get_ics_filepath('non_dst_error')])
+    assert result.exception
+    expected = ValueError("Invalid iCalendar duration: PT-2H")
+    assert expected.__class__ == result.exception.__class__
+    assert expected.args == result.exception.args
 
 def test_import(runner, monkeypatch):
     runner = runner()
diff --git a/tests/ics/non_dst_error.ics b/tests/ics/non_dst_error.ics
new file mode 100644
index 0000000..8b28f69
--- /dev/null
+++ b/tests/ics/non_dst_error.ics
@@ -0,0 +1,188 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//NS Internationaal B.V.//sales-v2//en
+BEGIN:VTIMEZONE
+TZID:Europe/Brussels
+LAST-MODIFIED:20221105T024525Z
+TZURL:http://www.tzurl.org/zoneinfo/Europe/Brussels
+X-LIC-LOCATION:Europe/Brussels
+X-PROLEPTIC-TZNAME:LMT
+BEGIN:STANDARD
+TZNAME:BMT
+TZOFFSETFROM:+0017
+TZOFFSETTO:+0017
+DTSTART:18800101T000000
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:WET
+TZOFFSETFROM:+0017
+TZOFFSETTO:+0000
+DTSTART:18920501T001730
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0000
+TZOFFSETTO:+0100
+DTSTART:19141108T000000
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+DTSTART:19161001T010000
+RDATE:19421102T030000
+RDATE:19431004T030000
+RDATE:19440917T030000
+RDATE:19450916T030000
+RDATE:19461007T030000
+RDATE:19770925T030000
+RDATE:19781001T030000
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+DTSTART:19170917T030000
+RRULE:FREQ=YEARLY;UNTIL=19180916T010000Z;BYDAY=3MO;BYMONTH=9
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:WET
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0000
+DTSTART:19181111T120000
+RDATE:19191005T000000
+RDATE:19201024T000000
+RDATE:19211026T000000
+RDATE:19391119T030000
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:WET
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0000
+DTSTART:19221008T000000
+RRULE:FREQ=YEARLY;UNTIL=19271001T230000Z;BYDAY=SU;BYMONTHDAY=2,3,4,5,6,7,8;
+ BYMONTH=10
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:WET
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0000
+DTSTART:19281007T030000
+RRULE:FREQ=YEARLY;UNTIL=19381002T020000Z;BYDAY=SU;BYMONTHDAY=2,3,4,5,6,7,8;
+ BYMONTH=10
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0100
+DTSTART:19770101T000000
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+DTSTART:19790930T030000
+RRULE:FREQ=YEARLY;UNTIL=19950924T010000Z;BYDAY=-1SU;BYMONTH=9
+END:STANDARD
+BEGIN:STANDARD
+TZNAME:CET
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0100
+DTSTART:19961027T030000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+END:STANDARD
+BEGIN:DAYLIGHT
+TZNAME:CEST
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+DTSTART:19160501T000000
+RDATE:19400520T030000
+RDATE:19430329T020000
+RDATE:19440403T020000
+RDATE:19450402T020000
+RDATE:19460519T020000
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+TZNAME:CEST
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+DTSTART:19170416T020000
+RRULE:FREQ=YEARLY;UNTIL=19180415T010000Z;BYDAY=3MO;BYMONTH=4
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+TZNAME:WEST
+TZOFFSETFROM:+0000
+TZOFFSETTO:+0100
+DTSTART:19190301T230000
+RDATE:19200214T230000
+RDATE:19210314T230000
+RDATE:19220325T230000
+RDATE:19230421T230000
+RDATE:19240329T230000
+RDATE:19250404T230000
+RDATE:19260417T230000
+RDATE:19270409T230000
+RDATE:19280414T230000
+RDATE:19290421T020000
+RDATE:19300413T020000
+RDATE:19310419T020000
+RDATE:19320403T020000
+RDATE:19330326T020000
+RDATE:19340408T020000
+RDATE:19350331T020000
+RDATE:19360419T020000
+RDATE:19370404T020000
+RDATE:19380327T020000
+RDATE:19390416T020000
+RDATE:19400225T020000
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+TZNAME:CEST
+TZOFFSETFROM:+0200
+TZOFFSETTO:+0200
+DTSTART:19440903T000000
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+TZNAME:CEST
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+DTSTART:19770403T020000
+RRULE:FREQ=YEARLY;UNTIL=19800406T010000Z;BYDAY=1SU;BYMONTH=4
+END:DAYLIGHT
+BEGIN:DAYLIGHT
+TZNAME:CEST
+TZOFFSETFROM:+0100
+TZOFFSETTO:+0200
+DTSTART:19810329T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:4e3e3186-28c6-42d4-81cf-eb4f56d587f1
+DTSTAMP:20230122T142045Z
+SUMMARY:Trip from Utrecht to Bruxelles Central/Brussel Centraal
+DESCRIPTION:Trip from Utrecht to Bruxelles Central/Brussel Centraal
+LOCATION:Utrecht
+URL:https://www.nsinternational.com/en/traintickets-v3/
+DTSTART;TZID=Europe/Brussels:20230203T151500
+DTEND;TZID=Europe/Brussels:20230203T180600
+BEGIN:VALARM
+ACTION:DISPLAY
+TRIGGER;RELATED=START:PT-2H
+END:VALARM
+END:VEVENT
+BEGIN:VEVENT
+UID:28d25a55-84cd-4564-910b-088066fd5244
+DTSTAMP:20230122T142045Z
+SUMMARY:Trip from Bruxelles Central/Brussel Centraal to Utrecht
+DESCRIPTION:Trip from Bruxelles Central/Brussel Centraal to Utrecht
+LOCATION:Bruxelles Central/Brussel Centraal
+URL:https://www.nsinternational.com/en/traintickets-v3/
+DTSTART;TZID=Europe/Brussels:20230206T095000
+DTEND;TZID=Europe/Brussels:20230206T125000
+BEGIN:VALARM
+ACTION:DISPLAY
+TRIGGER;RELATED=START:PT-2H
+END:VALARM
+END:VEVENT
+END:VCALENDAR