libecal: importing event with pseudo "Etc/UTC" timezone crashed (#593019)
authorPatrick Ohly <patrick.ohly@gmx.de>
Thu, 17 Sep 2009 07:11:29 +0000 (09:11 +0200)
committerPatrick Ohly <patrick.ohly@intel.com>
Tue, 22 Sep 2009 12:08:47 +0000 (14:08 +0200)
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
calendar/libecal/e-cal.c

index 0d7012b..57003ba 100644 (file)
@@ -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,
index a75f6ab..f3d8e04 100644 (file)
@@ -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;
                }