[gnome-todo] gtd-task: Avoid crash by using weak reference on GtdTaskList
- From: Victor Toso de Carvalho <victortoso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-todo] gtd-task: Avoid crash by using weak reference on GtdTaskList
- Date: Wed, 9 Nov 2016 13:40:57 +0000 (UTC)
commit f1a8e5c964a1b4939d4517aebaf0eaca05fea519
Author: Victor Toso <me victortoso com>
Date: Tue Nov 8 22:14:04 2016 +0100
gtd-task: Avoid crash by using weak reference on GtdTaskList
The crash happens as GtdTaskList was freed but GtdTask keeps a dangling
pointer to it. In gtd_manager_update_task(), gtd_task_get_list() is
called returning a dangling pointer which is provided to
gtd_task_list_get_provider(), causing the crash on GTD_IS_TASK_LIST().
As documentation in gtd_task_get_list() says that it holds a weak
reference to GtdTaskList but it did not do the weak_ref, this patch
tries to fix that.
If GtdTaskList is freed now, task_list_weak_notified() will set the
priv->list pointer to NULL.
Thread 1 "gnome-todo" received signal SIGSEGV, Segmentation fault.
0x0000000000426aa0 in GTD_IS_TASK_LIST (ptr=0x1251b70) at gtd-task-list.h:32
G_DECLARE_DERIVABLE_TYPE (GtdTaskList, gtd_task_list, GTD, TASK_LIST, GtdObject)
(gdb) bt
#0 in GTD_IS_TASK_LIST (ptr=0x1251b70) at gtd-task-list.h:32
#1 in gtd_task_list_get_provider (list=0x1251b70) at gtd-task-list.c:525
#2 in gtd_manager_update_task (manager=0x86cd00, task=0x12fc4a0)
at engine/gtd-manager.c:607
#3 in gtd_task_list_view__edit_task_finished (pane=0xe39f80, task=0x12fc4a0,
user_data=0x95ef90) at gtd-task-list-view.c:686
#4 in g_cclosure_marshal_VOID__OBJECTv (closure=0xe7feb0, return_value=0x0,
instance=0xe39f80, args=0x7fffffff9a38, marshal_data=0x0, n_params=1,
param_types=0x942930) at /jhbuild/glib/gobject/gmarshal.c:2102
#5 in _g_closure_invoke_va (closure=0xe7feb0, return_value=0x0, instance=0xe39f80,
args=0x7fffffff9a38, n_params=1, param_types=0x942930)
at /jhbuild/glib/gobject/gclosure.c:867
#6 in g_signal_emit_valist (instance=0xe39f80, signal_id=299, detail=0,
var_args=0x7fffffff9a38) at /jhbuild/glib/gobject/gsignal.c:3300
#7 in g_signal_emit (instance=0xe39f80, signal_id=299, detail=0)
at /jhbuild/glib/gobject/gsignal.c:3447
#8 in gtd_edit_pane_set_task (pane=0xe39f80, task=0x0) at gtd-edit-pane.c:446
#9 in gtd_edit_pane_dispose (object=0xe39f80) at gtd-edit-pane.c:258
https://bugzilla.gnome.org/show_bug.cgi?id=774120
src/gtd-task.c | 27 ++++++++++++++++++++++-----
1 files changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/src/gtd-task.c b/src/gtd-task.c
index dc84ff4..be87322 100644
--- a/src/gtd-task.c
+++ b/src/gtd-task.c
@@ -291,11 +291,24 @@ real_remove_subtask (GtdTask *self,
}
static void
+task_list_weak_notified (gpointer data,
+ GObject *where_the_object_was)
+{
+ GtdTask *task = GTD_TASK (data);
+ GtdTaskPrivate *priv = gtd_task_get_instance_private (task);
+ priv->list = NULL;
+}
+
+static void
gtd_task_finalize (GObject *object)
{
GtdTask *self = (GtdTask*) object;
GtdTaskPrivate *priv = gtd_task_get_instance_private (self);
+ if (priv->list)
+ g_object_weak_unref (G_OBJECT (priv->list), task_list_weak_notified, self);
+
+ priv->list = NULL;
g_free (priv->description);
g_object_unref (priv->component);
@@ -1076,11 +1089,15 @@ gtd_task_set_list (GtdTask *task,
priv = gtd_task_get_instance_private (task);
- if (priv->list != list)
- {
- priv->list = list;
- g_object_notify (G_OBJECT (task), "list");
- }
+ if (priv->list == list)
+ return;
+
+ if (priv->list)
+ g_object_weak_unref (G_OBJECT (priv->list), task_list_weak_notified, task);
+
+ priv->list = list;
+ g_object_weak_ref (G_OBJECT (priv->list), task_list_weak_notified, task);
+ g_object_notify (G_OBJECT (task), "list");
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]