Khal crashes because the event it created contains incorrect timezone
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 3.1k
- Forks
- 233
- Avg merge
- 1h 44m
- Merged PRs (30d)
- 1
Description
I did not investigated this to the full extent, but it seems that there some bug in khal where it creates incorrect events with regards to day light saving. See #817 and #755.
In my case I compared two events created by khal and noticed that one of them was missing part of the timezone details. Now both of these events create a timezone named 'local'. This ticket is about a crash that occurs when khal reads this timezone from the cache for the other event. I have a feeling like it is using the incomplete timezone from event A when rendering event B or something along these lines. The cache definitely seemed incorrectly constructed as I am able to avoid it by renaming the files, eg event1 -> event3, makes that the order in which they are loading is reversed and trigger or cancel the crash.
To trigger:
- empty the cache
rm /home/[user]/.local/share/khal/khal.db - run
ikhalonce to rebuild the cache. - exit
- run
ikhala second time
If it did not crash, reverse the files load order (eg mv event1.ics event3.ics) and try again.
$ khal --version
khal, version 0.9.10
One event:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PIMUTILS.ORG//NONSGML khal / icalendar //EN
BEGIN:VTIMEZONE
TZID:local
BEGIN:STANDARD
DTSTART;VALUE=DATE-TIME:20181104T010000
TZNAME:PST
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
END:STANDARD
BEGIN:DAYLIGHT
DTSTART;VALUE=DATE-TIME:20190310T030000
TZNAME:PDT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
SUMMARY:event2
DTSTART;TZID=local;VALUE=DATE-TIME:20190304T103000
DTEND;TZID=local;VALUE=DATE-TIME:20190304T113000
UID:event2uid
SEQUENCE:0
END:VEVENT
END:VCALENDAR
The other event:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//PIMUTILS.ORG//NONSGML khal / icalendar //EN
BEGIN:VTIMEZONE
TZID:local
BEGIN:DAYLIGHT
DTSTART;VALUE=DATE-TIME:20190310T030000
TZNAME:PDT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
SUMMARY:event1
DTSTART;TZID=local;VALUE=DATE-TIME:20190322T150000
DTEND;TZID=local;VALUE=DATE-TIME:20190325T160000
UID:event1uid
SEQUENCE:0
END:VEVENT
END:VCALENDAR
The crash:
debug: [sqlite]
debug: path: /home/[user]/.local/share/khal/khal.db
debug: created version table
debug: tables for calendar test exist
Traceback (most recent call last):
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 1300, in start_pane
loop.run()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 286, in run
self._run()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 384, in _run
self.event_loop.run()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 788, in run
self._loop()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 816, in _loop
self._entering_idle()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 777, in _entering_idle
callback()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 572, in entering_idle
self.draw_screen()
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/main_loop.py", line 586, in draw_screen
canvas = self._topmost_widget.render(self.screen_size, focus=True)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/wimp.py", line 638, in render
self._update_overlay(size, focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/wimp.py", line 618, in _update_overlay
canv = self._original_widget.render(size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/container.py", line 1086, in render
focus and self.focus_part == 'body')
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 1151, in render
rval = super(ClassicView, self).render(size, focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 1765, in render
canv = get_delegate(, self).render(size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/container.py", line 2087, in render
focus = focus and self.focus_position == i)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/widgets.py", line 666, in render
return super().render(size, focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 1765, in render
canv = get_delegate(self).render(size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/container.py", line 1529, in render
canv = w.render((maxcol, rows), focus=focus and item_focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/container.py", line 2087, in render
focus = focus and self.focus_position == i)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 931, in render
return super().render(a, focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 1765, in render
canv = get_delegate(self).render(size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/container.py", line 1529, in render
canv = w.render((maxcol, rows), focus=focus and item_focus)
File "/home/[user]/.local/lib/python3.6/site-packages/urwid/widget.py", line 144, in cached_render
canv = fn(self, size, focus=focus)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 281, in render
self.body._autoextend()
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 450, in _autoextend
pile = self._get_events(self._last_day)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/ui/__init__.py", line 475, in _get_events
self.events = sorted(self._collection.get_events_on(day))
File "/home/[user]/.local/lib/python3.6/site-packages/khal/khalendar/khalendar.py", line 148, in <genexpr>
return (self._cover_event(event) for event in events)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/khalendar/backend.py", line 482, in get_localized
yield self.construct_event(item, href, start, end, ref, etag, calendar, dtype)
File "/home/[user]/.local/lib/python3.6/site-packages/khal/khalendar/backend.py", line 561, in construct_event
ref=ref,
File "/home/[user]/.local/lib/python3.6/site-packages/khal/khalendar/event.py", line 151, in fromString
calendar_collection = icalendar.Calendar.from_ical(event_str)
File "/home/[user]/.local/lib/python3.6/site-packages/icalendar/cal.py", line 369, in from_ical
_timezone_cache[component['TZID']] = component.to_tz()
File "/home/[user]/.local/lib/python3.6/site-packages/icalendar/cal.py", line 642, in to_tz
assert dst_offset is not False
AssertionError
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the crash by rebuilding khal.db and running ikhal twice with the two supplied ICS files, then start at khal/khalendar/event.py in fromString and khal/khalendar/backend.py in construct_event. Trace the call into icalendar.Calendar.from_ical and its timezone assertion; done means the same cached events load in ikhal without crashing regardless of file load order.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100