[libdazzle: 1/2] task-cache: Prevent reference to a freed task cache




commit 9595afa7be6c40dc60ca4a537431ed0c52c33e93
Author: Corentin Noël <corentin noel collabora com>
Date:   Fri Jan 28 10:23:17 2022 +0100

    task-cache: Prevent reference to a freed task cache
    
    As the CancelledData doesn't hold a reference to a DzlTaskCache, it is possible
    for the GTask holding it to actually finishing after the DzlTaskCache has been
    finalized, do not unnecessarily store the DzlTaskCache reference but what we
    actually need from it.

 src/cache/dzl-task-cache.c | 16 ++++++----------
 1 file changed, 6 insertions(+), 10 deletions(-)
---
diff --git a/src/cache/dzl-task-cache.c b/src/cache/dzl-task-cache.c
index 0af7ff3..c37bd38 100644
--- a/src/cache/dzl-task-cache.c
+++ b/src/cache/dzl-task-cache.c
@@ -36,10 +36,10 @@ typedef struct
 
 typedef struct
 {
-  DzlTaskCache *self;
-  GCancellable *cancellable;
-  gpointer      key;
-  gulong        cancelled_id;
+  GCancellable   *cancellable;
+  gpointer        key;
+  GBoxedFreeFunc  key_destroy_func;
+  gulong          cancelled_id;
 } CancelledData;
 
 typedef struct
@@ -228,14 +228,12 @@ cancelled_data_free (gpointer data)
 {
   CancelledData *cancelled = data;
 
-  g_clear_pointer (&cancelled->key, cancelled->self->key_destroy_func);
+  g_clear_pointer (&cancelled->key, cancelled->key_destroy_func);
 
   g_cancellable_disconnect (cancelled->cancellable, cancelled->cancelled_id);
   cancelled->cancelled_id = 0;
   g_clear_object (&cancelled->cancellable);
 
-  cancelled->self = NULL;
-
   g_slice_free (CancelledData, cancelled);
 }
 
@@ -248,9 +246,9 @@ cancelled_data_new (DzlTaskCache  *self,
   CancelledData *ret;
 
   ret = g_slice_new0 (CancelledData);
-  ret->self = self;
   ret->cancellable = (cancellable != NULL) ? g_object_ref (cancellable) : NULL;
   ret->key = self->key_copy_func ((gpointer)key);
+  ret->key_destroy_func = self->key_destroy_func;
   ret->cancelled_id = cancelled_id;
 
   return ret;
@@ -454,7 +452,6 @@ dzl_task_cache_cancel_in_idle (gpointer user_data)
   g_assert (DZL_IS_TASK_CACHE (self));
   g_assert (G_IS_CANCELLABLE (cancellable));
   g_assert (data != NULL);
-  g_assert (data->self == self);
   g_assert (data->cancellable == cancellable);
 
   if ((queued = g_hash_table_lookup (self->queued, data->key)))
@@ -512,7 +509,6 @@ dzl_task_cache_cancelled_cb (GCancellable *cancellable,
 
   g_assert (DZL_IS_TASK_CACHE (self));
   g_assert (data != NULL);
-  g_assert (data->self == self);
   g_assert (data->cancellable == cancellable);
 
   source = g_idle_source_new ();


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