Repository: collective/icalendar

Issue:
Offsets larger than 24h?
At https://github.com/geier/khal/issues/140 there is a user whose offset values are not accepted by icalendar. I have no idea what is going on in that iCalendar file. Anybody got any ideas?


Discussion:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 5119c87..dc581d9 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -10,7 +10,8 @@ Breaking changes:
 
 New features:
 
-- *add item here*
+- added vUTCOffset.ignore_exceptions to allow surpressing of failed TZOFFSET
+  parsing (for now this ignores the check for offsets > 24h) [geier]
 
 Bug fixes:
 
diff --git a/src/icalendar/prop.py b/src/icalendar/prop.py
index f084e84..5c705c2 100644
--- a/src/icalendar/prop.py
+++ b/src/icalendar/prop.py
@@ -792,6 +792,11 @@ class vUTCOffset(object):
     """Renders itself as a utc offset.
     """
 
+    ignore_exceptions = False   # if True, and we cannot parse this
+                                # component, we will silently ignore
+                                # it, rather than let the exception
+                                # propagate upwards
+
     def __init__(self, td):
         if not isinstance(td, timedelta):
             raise ValueError('Offset value MUST be a timedelta instance')
@@ -831,7 +836,7 @@ class vUTCOffset(object):
             offset = timedelta(hours=hours, minutes=minutes, seconds=seconds)
         except:
             raise ValueError('Expected utc offset, got: %s' % ical)
-        if offset >= timedelta(hours=24):
+        if not cls.ignore_exceptions and offset >= timedelta(hours=24):
             raise ValueError(
                 'Offset must be less than 24 hours, was %s' % ical)
         if sign == '-':


Test patch:
diff --git a/src/icalendar/tests/test_unit_cal.py b/src/icalendar/tests/test_unit_cal.py
index 0cda117..1082ce7 100644
--- a/src/icalendar/tests/test_unit_cal.py
+++ b/src/icalendar/tests/test_unit_cal.py
@@ -430,3 +430,26 @@ class TestCal(unittest.TestCase):
                 for e in icalendar.cal.Calendar.from_ical(s).walk('VEVENT')],
             [[], [('EXDATE', "Expected datetime, date, or time, got: ''")]]
         )
+
+    def test_cal_strict_parsing(self):
+        cal_str = b'\r\n'.join(
+            [
+                b'BEGIN:VCALENDAR',
+                b'BEGIN:VTIMEZONE',
+                b'TZID:Europe/Prague',
+                b'BEGIN:STANDARD',
+                b'DTSTART:18500101T000000',
+                b'TZNAME:PMT',
+                b'TZOFFSETFROM:+5744',
+                b'TZOFFSETTO:+5744',
+                b'END:STANDARD',
+                b'END:VTIMEZONE',
+                b'END:VCALENDAR',
+                b'',
+            ]
+        )
+
+        self.assertRaises(ValueError, icalendar.Calendar.from_ical, cal_str)
+        icalendar.vUTCOffset.ignore_exceptions = True
+        self.assertEqual(icalendar.Calendar.from_ical(cal_str).to_ical(), cal_str)
+        icalendar.vUTCOffset.ignore_exceptions = False