From ccea859f88844c0cc3a94857e47eade6b1257cba Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 17 Sep 2009 09:11:29 +0200 Subject: [PATCH] libecal: importing event with pseudo "Etc/UTC" timezone crashed (#593019) The problem was two-fold: first, e_cal_match_timezone() recognized the pseudo VTIMEZONE as matching the internal "UTC". Then e_cal_get_timezone() failed to extract this internal VTIMEZONE because there is no real definition for it, leading to an assert which terminates the caller. Matching to "UTC" is also problematic because e_cal_match_timezones() will use it for the imported event, which then cannot be exported properly (leads to TZID=UTC without VTIMEZONE definition). Therefore this patch removes the mapping to "UTC" in e_cal_match_timezone(). It also fixes e_cal_get_timezone() so that it does not assert and returns an error code, as originally intented, although that should no longer happen with the change to e_cal_match_timezone(). --- calendar/libecal/e-cal-check-timezones.c | 23 +++++++++++++++++++---- calendar/libecal/e-cal.c | 4 +--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/calendar/libecal/e-cal-check-timezones.c b/calendar/libecal/e-cal-check-timezones.c index 0d7012b..57003ba 100644 --- a/calendar/libecal/e-cal-check-timezones.c +++ b/calendar/libecal/e-cal-check-timezones.c @@ -69,7 +69,7 @@ static const gchar *e_cal_match_location(const gchar *location) const gchar *e_cal_match_tzid(const gchar *tzid) { const gchar *location; - const gchar *systzid; + const gchar *systzid = NULL; gsize len = strlen(tzid); gssize eostr; @@ -95,7 +95,7 @@ const gchar *e_cal_match_tzid(const gchar *tzid) systzid = e_cal_match_tzid(strippedtzid); g_free(strippedtzid); if (systzid) { - return systzid; + goto done; } } } @@ -113,13 +113,28 @@ const gchar *e_cal_match_tzid(const gchar *tzid) location + 1 : location); if (systzid) { - return systzid; + goto done; } } /* TODO: lookup table for Exchange TZIDs */ - return NULL; + done: + if (systzid && !strcmp(systzid, "UTC")) { + /** + * UTC is special: it doesn't have a real VTIMEZONE in + * EDS. Matching some pseudo VTTIMEZONE with UTC in the TZID + * to our internal UTC "timezone" breaks + * e_cal_check_timezones() (it patches the event to use + * TZID=UTC, which cannot be exported correctly later on) and + * e_cal_get_timezone() (triggers an assert). + * + * So better avoid matching against it... + */ + return NULL; + } else { + return systzid; + } } static void patch_tzids(icalcomponent *subcomp, diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c index a75f6ab..f3d8e04 100644 --- a/calendar/libecal/e-cal.c +++ b/calendar/libecal/e-cal.c @@ -4678,7 +4678,7 @@ e_cal_get_timezone (ECal *ecal, const gchar *tzid, icaltimezone **zone, GError * CORBA_Environment ev; ECalendarStatus status = E_CALENDAR_STATUS_OK; ECalendarOp *our_op; - icalcomponent *icalcomp; + icalcomponent *icalcomp = NULL; const gchar *systzid; e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG); @@ -4777,7 +4777,6 @@ e_cal_get_timezone (ECal *ecal, const gchar *tzid, icaltimezone **zone, GError * * caller. */ icaltimezone *syszone = icaltimezone_get_builtin_timezone_from_tzid (systzid); - g_assert (syszone); if (syszone) { gboolean found = FALSE; icalproperty *prop; @@ -4793,7 +4792,6 @@ e_cal_get_timezone (ECal *ecal, const gchar *tzid, icaltimezone **zone, GError * prop = icalcomponent_get_next_property(icalcomp, ICAL_ANY_PROPERTY); } - g_assert (found); } else { status = E_CALENDAR_STATUS_INVALID_OBJECT; } -- 2.7.4