[evolution/evolution-3-12] Bug 676471 - Double free when sorting by date columns in calendar



commit ca64c2654a52ab8ce698f76a1cc431f9bb5970bf
Author: Milan Crha <mcrha redhat com>
Date:   Tue Nov 4 15:34:58 2014 +0100

    Bug 676471 - Double free when sorting by date columns in calendar

 calendar/gui/e-cal-model-calendar.c  |   16 ++-----
 calendar/gui/e-cal-model-tasks.c     |   18 +++-----
 calendar/gui/e-cal-model.c           |   79 ++++++++++++++++++---------------
 calendar/gui/e-cal-model.h           |    4 ++
 calendar/gui/e-cell-date-edit-text.c |    7 +++-
 5 files changed, 64 insertions(+), 60 deletions(-)
---
diff --git a/calendar/gui/e-cal-model-calendar.c b/calendar/gui/e-cal-model-calendar.c
index b3099cd..b211f4c 100644
--- a/calendar/gui/e-cal-model-calendar.c
+++ b/calendar/gui/e-cal-model-calendar.c
@@ -94,7 +94,7 @@ get_dtend (ECalModelCalendar *model,
                        comp_data->dtend->zone = NULL;
        }
 
-       return comp_data->dtend;
+       return e_cal_model_copy_cell_date_value (comp_data->dtend);
 }
 
 static gpointer
@@ -400,16 +400,7 @@ cal_model_calendar_duplicate_value (ETableModel *etm,
 
        switch (col) {
        case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
-               if (value) {
-                       ECellDateEditValue *dv, *orig_dv;
-
-                       orig_dv = (ECellDateEditValue *) value;
-                       dv = g_new0 (ECellDateEditValue, 1);
-                       *dv = *orig_dv;
-
-                       return dv;
-               }
-               break;
+               return e_cal_model_copy_cell_date_value (value);
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                return g_strdup (value);
@@ -432,6 +423,9 @@ cal_model_calendar_free_value (ETableModel *etm,
 
        switch (col) {
        case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
+               if (value)
+                       g_free (value);
+               break;
        case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
                break;
diff --git a/calendar/gui/e-cal-model-tasks.c b/calendar/gui/e-cal-model-tasks.c
index f07d9bf..ee6123c 100644
--- a/calendar/gui/e-cal-model-tasks.c
+++ b/calendar/gui/e-cal-model-tasks.c
@@ -207,7 +207,7 @@ get_completed (ECalModelComponent *comp_data)
                        comp_data->completed->zone = NULL;
        }
 
-       return comp_data->completed;
+       return e_cal_model_copy_cell_date_value (comp_data->completed);
 }
 
 static ECellDateEditValue *
@@ -237,7 +237,7 @@ get_due (ECalModelComponent *comp_data)
                        comp_data->due->zone = NULL;
        }
 
-       return comp_data->due;
+       return e_cal_model_copy_cell_date_value (comp_data->due);
 }
 
 static gpointer
@@ -1027,16 +1027,7 @@ cal_model_tasks_duplicate_value (ETableModel *etm,
                return g_strdup (value);
        case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
        case E_CAL_MODEL_TASKS_FIELD_DUE :
-               if (value) {
-                       ECellDateEditValue *dv, *orig_dv;
-
-                       orig_dv = (ECellDateEditValue *) value;
-                       dv = g_new0 (ECellDateEditValue, 1);
-                       *dv = *orig_dv;
-
-                       return dv;
-               }
-               break;
+               return e_cal_model_copy_cell_date_value (value);
 
        case E_CAL_MODEL_TASKS_FIELD_COMPLETE :
        case E_CAL_MODEL_TASKS_FIELD_PERCENT :
@@ -1062,6 +1053,9 @@ cal_model_tasks_free_value (ETableModel *etm,
        switch (col) {
        case E_CAL_MODEL_TASKS_FIELD_COMPLETED :
        case E_CAL_MODEL_TASKS_FIELD_DUE :
+               if (value)
+                       g_free (value);
+               break;
        case E_CAL_MODEL_TASKS_FIELD_GEO :
        case E_CAL_MODEL_TASKS_FIELD_PRIORITY :
        case E_CAL_MODEL_TASKS_FIELD_STATUS :
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index f7f3d6e..05ffef5 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -540,7 +540,7 @@ get_dtstart (ECalModel *model,
                        comp_data->dtstart->zone = NULL;
        }
 
-       return comp_data->dtstart;
+       return e_cal_model_copy_cell_date_value (comp_data->dtstart);
 }
 
 static ECellDateEditValue *
@@ -548,40 +548,39 @@ get_datetime_from_utc (ECalModel *model,
                        ECalModelComponent *comp_data,
                        icalproperty_kind propkind,
                        struct icaltimetype (*get_value) (const icalproperty *prop),
-                                                         ECellDateEditValue **buffer)
+                      ECellDateEditValue **buffer)
 {
-       ECalModelPrivate *priv;
-       struct icaltimetype tt_value;
-       icalproperty *prop;
-       ECellDateEditValue *res;
+       g_return_val_if_fail (buffer != NULL, NULL);
 
-       g_return_val_if_fail (buffer!= NULL, NULL);
-
-       if (*buffer)
-               return *buffer;
+       if (!*buffer) {
+               ECalModelPrivate *priv;
+               struct icaltimetype tt_value;
+               icalproperty *prop;
+               ECellDateEditValue *res;
 
-       priv = model->priv;
+               priv = model->priv;
 
-       prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
-       if (!prop)
-               return NULL;
+               prop = icalcomponent_get_first_property (comp_data->icalcomp, propkind);
+               if (!prop)
+                       return NULL;
 
-       tt_value = get_value (prop);
+               tt_value = get_value (prop);
 
-       /* these are always in UTC, thus convert to default zone, if any and done */
-       if (priv->zone)
-               icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
+               /* these are always in UTC, thus convert to default zone, if any and done */
+               if (priv->zone)
+                       icaltimezone_convert_time (&tt_value, icaltimezone_get_utc_timezone (), priv->zone);
 
-       if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
-               return NULL;
+               if (!icaltime_is_valid_time (tt_value) || icaltime_is_null_time (tt_value))
+                       return NULL;
 
-       res = g_new0 (ECellDateEditValue, 1);
-       res->tt = tt_value;
-       res->zone = NULL;
+               res = g_new0 (ECellDateEditValue, 1);
+               res->tt = tt_value;
+               res->zone = NULL;
 
-       *buffer = res;
+               *buffer = res;
+       }
 
-       return res;
+       return e_cal_model_copy_cell_date_value (*buffer);
 }
 
 static gpointer
@@ -1515,16 +1514,7 @@ cal_model_duplicate_value (ETableModel *etm,
        case E_CAL_MODEL_FIELD_DTSTART :
        case E_CAL_MODEL_FIELD_CREATED :
        case E_CAL_MODEL_FIELD_LASTMODIFIED :
-               if (value) {
-                       ECellDateEditValue *dv, *orig_dv;
-
-                       orig_dv = (ECellDateEditValue *) value;
-                       dv = g_new0 (ECellDateEditValue, 1);
-                       *dv = *orig_dv;
-
-                       return dv;
-               }
-               break;
+               return e_cal_model_copy_cell_date_value (value);
        }
 
        return NULL;
@@ -1548,8 +1538,8 @@ cal_model_free_value (ETableModel *etm,
        case E_CAL_MODEL_FIELD_HAS_ALARMS :
        case E_CAL_MODEL_FIELD_ICON :
        case E_CAL_MODEL_FIELD_COLOR :
-       case E_CAL_MODEL_FIELD_DTSTART:
                break;
+       case E_CAL_MODEL_FIELD_DTSTART:
        case E_CAL_MODEL_FIELD_CREATED :
        case E_CAL_MODEL_FIELD_LASTMODIFIED :
                if (value)
@@ -4357,3 +4347,20 @@ e_cal_model_set_default_time_func (ECalModel *model,
        model->priv->get_default_time = func;
        model->priv->get_default_time_user_data = user_data;
 }
+
+
+ECellDateEditValue *
+e_cal_model_copy_cell_date_value (const ECellDateEditValue *value)
+{
+       ECellDateEditValue *copy;
+
+       if (!value)
+               return NULL;
+
+
+       copy = g_new0 (ECellDateEditValue, 1);
+       copy->tt = value->tt;
+       copy->zone = value->zone;
+
+       return copy;
+}
diff --git a/calendar/gui/e-cal-model.h b/calendar/gui/e-cal-model.h
index 6711c81..98130ed 100644
--- a/calendar/gui/e-cal-model.h
+++ b/calendar/gui/e-cal-model.h
@@ -326,6 +326,10 @@ void               e_cal_model_update_status_message
                                                 const gchar *message,
                                                 gdouble percent);
 
+ECellDateEditValue *
+               e_cal_model_copy_cell_date_value
+                                               (const ECellDateEditValue *value);
+
 G_END_DECLS
 
 #endif /* E_CAL_MODEL_H */
diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c
index 1d13953..103e27d 100644
--- a/calendar/gui/e-cell-date-edit-text.c
+++ b/calendar/gui/e-cell-date-edit-text.c
@@ -115,6 +115,7 @@ cell_date_edit_text_get_text (ECellText *cell,
        ECellDateEditValue *dv = e_table_model_value_at (model, col, row);
        icaltimezone *timezone;
        struct tm tmp_tm;
+       gchar *res;
 
        if (!dv)
                return g_strdup ("");
@@ -127,9 +128,13 @@ cell_date_edit_text_get_text (ECellText *cell,
         * it will be set to the current timezone. See set_value (). */
        tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, timezone);
 
-       return e_datetime_format_format_tm (
+       res = e_datetime_format_format_tm (
                "calendar", "table", dv->tt.is_date ?
                DTFormatKindDate : DTFormatKindDateTime, &tmp_tm);
+
+       e_table_model_free_value (model, col, dv);
+
+       return res;
 }
 
 static void


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