[gnome-calendar/mcatanzaro/#419: 1/2] Fix crashes when e_cal_util_get_system_timezone() returns NULL



commit 8e6a3b9f3f6b3127b967c1cfc70a7362e7fe929a
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Thu Sep 19 15:38:26 2019 -0500

    Fix crashes when e_cal_util_get_system_timezone() returns NULL
    
    The return value is nullable, but gnome-calendar fails to check it.
    
    Because the nullable return value is inconvenient for us, we can instead
    add and use gcal_context_get_icaltimezone() to supplement the existing
    gcal_context_get_timezone().
    
    We'll also need a function to convert from GTimeZone to ICalTimezone,
    gcal_timezone_to_icaltimezone().
    
    Fixes #419

 src/core/gcal-event.c            | 16 ++++++++++++----
 src/core/gcal-manager.c          | 36 ++++++++++++++++++++++++++++++++----
 src/search/gcal-search-engine.c  |  4 +++-
 src/utils/gcal-date-time-utils.c | 20 ++++++++++++++++++++
 src/utils/gcal-date-time-utils.h |  2 ++
 src/utils/gcal-utils.c           | 34 +++++++++++++++++++++++++---------
 6 files changed, 94 insertions(+), 18 deletions(-)
---
diff --git a/src/core/gcal-event.c b/src/core/gcal-event.c
index 5bb91256..3ae3fcad 100644
--- a/src/core/gcal-event.c
+++ b/src/core/gcal-event.c
@@ -20,6 +20,7 @@
 
 #include "gconstructor.h"
 #include "gcal-application.h"
+#include "gcal-context.h"
 #include "gcal-debug.h"
 #include "gcal-event.h"
 #include "gcal-utils.h"
@@ -223,12 +224,17 @@ static ECalComponentDateTime*
 build_component_from_datetime (GcalEvent *self,
                                GDateTime *dt)
 {
+  GcalApplication *application;
+  GcalContext *context;
   ICalTime *itt;
   gchar *tzid;
 
   if (!dt)
     return NULL;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
+
   itt = gcal_date_time_to_icaltime (dt);
 
   if (self->all_day)
@@ -238,11 +244,13 @@ build_component_from_datetime (GcalEvent *self,
     }
   else
     {
-      ICalTimezone *zone;
+      ICalTimezone *tz;
+      GTimeZone *zone;
 
-      zone = e_cal_util_get_system_timezone ();
-      i_cal_time_set_timezone (itt, zone);
-      tzid = zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL;
+      zone = gcal_context_get_timezone (context);
+      tz = gcal_timezone_to_icaltimezone (zone);
+      i_cal_time_set_timezone (itt, tz);
+      tzid = g_strdup (i_cal_timezone_get_tzid (tz));
     }
 
   /* Call it after setting the timezone, because the DATE values do not let set the timezone */
diff --git a/src/core/gcal-manager.c b/src/core/gcal-manager.c
index 7f051632..fbbb9fcf 100644
--- a/src/core/gcal-manager.c
+++ b/src/core/gcal-manager.c
@@ -18,6 +18,8 @@
 
 #define G_LOG_DOMAIN "GcalManager"
 
+#include "gcal-application.h"
+#include "gcal-context.h"
 #include "gcal-debug.h"
 #include "gcal-manager.h"
 #include "gcal-utils.h"
@@ -877,11 +879,18 @@ void
 gcal_manager_setup_shell_search (GcalManager             *self,
                                  ECalDataModelSubscriber *subscriber)
 {
+  GcalApplication *application;
+  GcalContext *context;
+  GTimeZone *zone;
+
   g_return_if_fail (GCAL_IS_MANAGER (self));
 
   if (self->shell_search_data_model)
     return;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
+
   self->shell_search_data_model = e_cal_data_model_new (gcal_thread_submit_job);
   g_signal_connect_object (self->shell_search_data_model,
                            "view-state-changed",
@@ -890,7 +899,9 @@ gcal_manager_setup_shell_search (GcalManager             *self,
                            G_CONNECT_SWAPPED);
 
   e_cal_data_model_set_expand_recurrences (self->shell_search_data_model, TRUE);
-  e_cal_data_model_set_timezone (self->shell_search_data_model, e_cal_util_get_system_timezone ());
+
+  zone = gcal_context_get_timezone (context);
+  e_cal_data_model_set_timezone (self->shell_search_data_model, gcal_timezone_to_icaltimezone (zone));
 
   self->search_view_data = g_new0 (ViewStateData, 1);
   self->search_view_data->subscriber = subscriber;
@@ -1420,7 +1431,11 @@ gcal_manager_get_events (GcalManager *self,
                          ICalTime    *start_date,
                          ICalTime    *end_date)
 {
+  GcalApplication *application;
+  GcalContext *context;
   time_t range_start, range_end;
+  GTimeZone *zone;
+  ICalTimezone *tz;
   GatherEventData data = {
     .manager = self,
     .events = NULL,
@@ -1428,10 +1443,15 @@ gcal_manager_get_events (GcalManager *self,
 
   GCAL_ENTRY;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
+
   g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
 
-  range_start = i_cal_time_as_timet_with_zone (start_date, e_cal_util_get_system_timezone ());
-  range_end = i_cal_time_as_timet_with_zone (end_date, e_cal_util_get_system_timezone ());
+  zone = gcal_context_get_timezone (context);
+  tz = gcal_timezone_to_icaltimezone (zone);
+  range_start = i_cal_time_as_timet_with_zone (start_date, tz);
+  range_end = i_cal_time_as_timet_with_zone (end_date, tz);
 
   e_cal_data_model_foreach_component (self->e_data_model,
                                       range_start,
@@ -1521,9 +1541,15 @@ gcal_manager_startup (GcalManager *self)
   GList *sources, *l;
   GError *error = NULL;
   ESourceCredentialsProvider *credentials_provider;
+  GcalApplication *application;
+  GcalContext *context;
+  GTimeZone *zone;
 
   GCAL_ENTRY;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
+
   self->clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
                                          (GEqualFunc) e_source_equal,
                                          g_object_unref,
@@ -1621,7 +1647,9 @@ gcal_manager_startup (GcalManager *self)
   self->e_data_model = e_cal_data_model_new (gcal_thread_submit_job);
 
   e_cal_data_model_set_expand_recurrences (self->e_data_model, TRUE);
-  e_cal_data_model_set_timezone (self->e_data_model, e_cal_util_get_system_timezone ());
+
+  zone = gcal_context_get_timezone (context);
+  e_cal_data_model_set_timezone (self->e_data_model, gcal_timezone_to_icaltimezone (zone));
 
   sources = e_source_registry_list_enabled (self->source_registry, E_SOURCE_EXTENSION_CALENDAR);
 
diff --git a/src/search/gcal-search-engine.c b/src/search/gcal-search-engine.c
index eadbf80d..7cf44699 100644
--- a/src/search/gcal-search-engine.c
+++ b/src/search/gcal-search-engine.c
@@ -177,14 +177,16 @@ gcal_search_engine_constructed (GObject *object)
 {
   GcalSearchEngine *self = (GcalSearchEngine *)object;
   GcalManager *manager;
+  GTimeZone *zone;
 
   G_OBJECT_CLASS (gcal_search_engine_parent_class)->constructed (object);
 
   /* Setup the data model */
   self->data_model = e_cal_data_model_new (gcal_thread_submit_job);
   e_cal_data_model_set_expand_recurrences (self->data_model, TRUE);
-  e_cal_data_model_set_timezone (self->data_model, e_cal_util_get_system_timezone ());
 
+  zone = gcal_context_get_timezone (self->context);
+  e_cal_data_model_set_timezone (self->data_model, gcal_timezone_to_icaltimezone (zone));
 
   manager = gcal_context_get_manager (self->context);
   g_signal_connect_object (manager, "calendar-added", G_CALLBACK (on_manager_calendar_added_cb), self, 0);
diff --git a/src/utils/gcal-date-time-utils.c b/src/utils/gcal-date-time-utils.c
index 45ea57a6..11dcb5a8 100644
--- a/src/utils/gcal-date-time-utils.c
+++ b/src/utils/gcal-date-time-utils.c
@@ -230,3 +230,23 @@ gcal_date_time_from_icaltime (const ICalTime *date)
   return g_steal_pointer (&dt);
 }
 
+/**
+ * @tz: a #GTimezone
+ *
+ * Returns an #ICalTimezone corresponding to @tz.
+ *
+ * Returns: (transfer none): an #ICalTimezone.
+ */
+ICalTimezone*
+gcal_timezone_to_icaltimezone (GTimeZone *tz)
+{
+  ICalTimezone *ical_tz;
+  const gchar *tzid;
+
+  tzid = g_time_zone_get_identifier (tz);
+  ical_tz = i_cal_timezone_get_builtin_timezone (tzid);
+
+  g_assert (ical_tz != NULL);
+  return ical_tz;
+}
+
diff --git a/src/utils/gcal-date-time-utils.h b/src/utils/gcal-date-time-utils.h
index 369082b0..50d9707e 100644
--- a/src/utils/gcal-date-time-utils.h
+++ b/src/utils/gcal-date-time-utils.h
@@ -51,4 +51,6 @@ gboolean             gcal_date_time_is_date                      (GDateTime
 
 GDateTime*           gcal_date_time_from_icaltime                (const ICalTime     *date);
 
+ICalTimezone*        gcal_timezone_to_icaltimezone               (GTimeZone          *tz);
+
 G_END_DECLS
diff --git a/src/utils/gcal-utils.c b/src/utils/gcal-utils.c
index c4aad0ad..995449d2 100644
--- a/src/utils/gcal-utils.c
+++ b/src/utils/gcal-utils.c
@@ -23,6 +23,8 @@
 /* langinfo.h in glibc 2.27 defines ALTMON_* only if _GNU_SOURCE is defined.  */
 #define _GNU_SOURCE
 
+#include "gcal-application.h"
+#include "gcal-context.h"
 #include "gcal-enums.h"
 #include "gcal-utils.h"
 #include "gcal-event-widget.h"
@@ -369,13 +371,17 @@ build_component_from_details (const gchar *summary,
                               GDateTime   *initial_date,
                               GDateTime   *final_date)
 {
+  GcalApplication *application;
+  GcalContext *context;
   ECalComponent *event;
   ECalComponentDateTime *dt;
   ECalComponentText *summ;
-  ICalTimezone *zone;
+  ICalTimezone *tz;
   ICalTime *itt;
   gboolean all_day;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
   event = e_cal_component_new ();
   e_cal_component_set_new_vtype (event, E_CAL_COMPONENT_EVENT);
 
@@ -391,18 +397,21 @@ build_component_from_details (const gchar *summary,
    */
   if (all_day)
     {
-      zone = i_cal_timezone_get_utc_timezone ();
+      tz = i_cal_timezone_get_utc_timezone ();
     }
   else
     {
-      zone = e_cal_util_get_system_timezone ();
+      GTimeZone *zone;
+
+      zone = gcal_context_get_timezone (context);
+      tz = gcal_timezone_to_icaltimezone (zone);
     }
 
   /* Start date */
   itt = gcal_date_time_to_icaltime (initial_date);
-  i_cal_time_set_timezone (itt, zone);
+  i_cal_time_set_timezone (itt, tz);
   i_cal_time_set_is_date (itt, all_day);
-  dt = e_cal_component_datetime_new_take (itt, zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL);
+  dt = e_cal_component_datetime_new_take (itt, tz ? g_strdup (i_cal_timezone_get_tzid (tz)) : NULL);
   e_cal_component_set_dtstart (event, dt);
 
   e_cal_component_datetime_free (dt);
@@ -412,9 +421,9 @@ build_component_from_details (const gchar *summary,
     final_date = g_date_time_add_days (initial_date, 1);
 
   itt = gcal_date_time_to_icaltime (final_date);
-  i_cal_time_set_timezone (itt, zone);
+  i_cal_time_set_timezone (itt, tz);
   i_cal_time_set_is_date (itt, all_day);
-  dt = e_cal_component_datetime_new_take (itt, zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL);
+  dt = e_cal_component_datetime_new_take (itt, tz ? g_strdup (i_cal_timezone_get_tzid (tz)) : NULL);
   e_cal_component_set_dtend (event, dt);
 
   e_cal_component_datetime_free (dt);
@@ -476,17 +485,24 @@ icaltime_compare_with_current (const ICalTime *date1,
                                const ICalTime *date2,
                                time_t         *current_time_t)
 {
+  GcalApplication *application;
+  GcalContext *context;
+  GTimeZone *zone;
   ICalTimezone *zone1, *zone2;
   gint result = 0;
   time_t start1, start2, diff1, diff2;
 
+  application = GCAL_APPLICATION (g_application_get_default ());
+  context = gcal_application_get_context (application);
+  zone = gcal_context_get_timezone (context);
+
   zone1 = i_cal_time_get_timezone (date1);
   if (!zone1)
-    zone1 = e_cal_util_get_system_timezone ();
+    zone1 = gcal_timezone_to_icaltimezone (zone);
 
   zone2 = i_cal_time_get_timezone (date2);
   if (!zone2)
-    zone2 = e_cal_util_get_system_timezone ();
+    zone2 = gcal_timezone_to_icaltimezone (zone);
 
   start1 = i_cal_time_as_timet_with_zone (date1, zone1);
   start2 = i_cal_time_as_timet_with_zone (date2, zone2);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]