Inconsistencies in TZID values for builtin timezones
Milan Crha
mcrha at redhat.com
Mon Jul 27 11:47:09 EDT 2020
Hi,
while investigating a downstream report [1] I realized that libical can
generate multiple different TZID values for a single time zone,
depending on how it was configured and how the timezone itself had been
read by libical.
First to give some background: the evolution-data-server's calendar
backends rely on the TZID. They can store all used timezones (in time
of adding the events) in the local iCalendar object, thus libical can
lookup for them in functions like icalcomponent_get_dtstart(), where
libical can prefill the icaltimetype::zone property if either the
parent component contains a timezone definition for that TZID, or the
TZID matches one of the builtin time zones, or when the TZID matches
one of the builtin locations (see the implementation of the
icalproperty_get_datetime_with_component()). Due to that the evolution-
data-server does not store the builtin time zones into its iCalendar
data, to save space and avoid duplication and to get up-to-date
timezone information.
The problem happens when libical itself changes its own TZID values,
because it cannot find the previously named TZID. I'm not talking about
changing icaltimezone.c::BUILTIN_TZID_PREFIX #define, I believe most of
the libical clients do not need to touch it (with
icaltimezone_set_tzid_prefix()), I'm talking about moving data between
machines or different builds of the libical. There are currently two
different names the libical can generate:
1) /freeassociation.sourceforge.net/Europe/London
2) /citadel.org/20190914_1/Europe/London
The first is when libical is configured with -DUSE_BUILTIN_TZDATA=OFF,
while the second, when it is configured with -DUSE_BUILTIN_TZDATA=ON.
There used to be also the third form:
3) /freeassociation.sourceforge.net/Tzfile/Europe/London
which had been returned from icaltzutil_fetch_timezone(), before [2]
(it was for libical 1.0.1).
The problem is when the user switches from 1) to 2) or vice versa, then
libical is not able to find its own timezone. In fact, the downstream
report ([1]) has an event, which has stored the variant 3) for the
timezone.
I hesitate to write a code in every client to try to find the time
zones in three different forms of the TZID, I'd rather like to see
libical to handle this on its own, transparently. After all, these
things are internal to libical. I think of some backward compatibility
code, to convert TZID of an old form to a new form.
What do you think? May I produce a patch for it?
You can argue that the applications (clients of libical) can use a
consistent prefix, when they declare their own with
icaltimezone_set_tzid_prefix(), but, as I said above, majority of the
clients do not touch it and I believe it's for good. Changing the
default prefix can eventually break interoperability, or even the old
events of that client, like happened in [1].
Bye,
Milan
P.S.: while testing these things I noticed the
icaltzutil_fetch_timezone() is always returning NULL, when libical is
configured with -DUSE_BUILTIN_TZDATA=ON. I do not think it's intended,
is it? Or is the icaltzutil_fetch_timezone() meant as a private
function?
[1] https://gitlab.gnome.org/GNOME/evolution-data-server/-/issues/238
[2] https://github.com/libical/libical/commit/a04eb3bbf4b6eb1be4a43dbc06c82565166dd526
More information about the libical-devel
mailing list