pimutils / pimutils/khal

Khal crashes because the event it created contains incorrect timezone

Open
#846 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: bug
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:

  1. empty the cache rm /home/[user]/.local/share/khal/khal.db
  2. run ikhal once to rebuild the cache.
  3. exit
  4. run ikhal a 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.