From 9a97446bebcc563eb4a52e6d17569e35383436d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= <amatej@redhat.com>
Date: Wed, 12 Oct 2022 08:23:58 +0200
Subject: [PATCH] Disconnect monitors in `dnf_repo_loader_finalize()`
 (RhBug:2070153)

This fixes a crash that could occur due to dangling monitors there we
executed even when the `DnfRepoLoader` was already freed.

https://bugzilla.redhat.com/show_bug.cgi?id=2070153

Conflict:NA
Reference:https://github.com/rpm-software-management/libdnf/commit/9a97446bebcc563eb4a52e6d17569e35383436d5
---
 libdnf/dnf-repo-loader.cpp | 73 +++++++++++++++++++++-----------------
 1 file changed, 40 insertions(+), 33 deletions(-)

diff --git a/libdnf/dnf-repo-loader.cpp b/libdnf/dnf-repo-loader.cpp
index c6d4faaaf3..a686ee251e 100644
--- a/libdnf/dnf-repo-loader.cpp
+++ b/libdnf/dnf-repo-loader.cpp
@@ -61,25 +61,6 @@ static guint signals[SIGNAL_LAST] = { 0 };
 G_DEFINE_TYPE_WITH_PRIVATE(DnfRepoLoader, dnf_repo_loader, G_TYPE_OBJECT)
 #define GET_PRIVATE(o) (static_cast<DnfRepoLoaderPrivate *>(dnf_repo_loader_get_instance_private (o)))
 
-/**
- * dnf_repo_loader_finalize:
- **/
-static void
-dnf_repo_loader_finalize(GObject *object)
-{
-    DnfRepoLoader *self = DNF_REPO_LOADER(object);
-    DnfRepoLoaderPrivate *priv = GET_PRIVATE(self);
-
-    if (priv->context != NULL)
-        g_object_remove_weak_pointer(G_OBJECT(priv->context),
-                                     (void **) &priv->context);
-    g_ptr_array_unref(priv->monitor_repos);
-    g_object_unref(priv->volume_monitor);
-    g_ptr_array_unref(priv->repos);
-
-    G_OBJECT_CLASS(dnf_repo_loader_parent_class)->finalize(object);
-}
-
 /**
  * dnf_repo_loader_invalidate:
  */
@@ -104,6 +85,46 @@ dnf_repo_loader_mount_changed_cb(GVolumeMonitor *vm, GMount *mount, DnfRepoLoade
     dnf_repo_loader_invalidate(self);
 }
 
+/**
+ * dnf_repo_loader_directory_changed_cb:
+ **/
+static void
+dnf_repo_loader_directory_changed_cb(GFileMonitor *monitor_,
+                                     GFile *file, GFile *other_file,
+                                     GFileMonitorEvent event_type,
+                                     DnfRepoLoader *self)
+{
+    g_debug("emit changed(ReposDir changed)");
+    g_signal_emit(self, signals[SIGNAL_CHANGED], 0);
+    dnf_repo_loader_invalidate(self);
+}
+
+/**
+ * dnf_repo_loader_finalize:
+ **/
+static void
+dnf_repo_loader_finalize(GObject *object)
+{
+    DnfRepoLoader *self = DNF_REPO_LOADER(object);
+    DnfRepoLoaderPrivate *priv = GET_PRIVATE(self);
+
+    if (priv->context != NULL)
+        g_object_remove_weak_pointer(G_OBJECT(priv->context),
+                                     (void **) &priv->context);
+    guint i;
+    for (i = 0; i < priv->monitor_repos->len; i++) {
+        auto repo_file_monitor = static_cast<GFileMonitor *>(g_ptr_array_index(priv->monitor_repos, i));
+        g_signal_handlers_disconnect_by_func(repo_file_monitor, (gpointer) dnf_repo_loader_directory_changed_cb, self);
+    }
+    g_ptr_array_unref(priv->monitor_repos);
+
+    g_signal_handlers_disconnect_by_func(priv->volume_monitor, (gpointer) dnf_repo_loader_mount_changed_cb, self);
+    g_object_unref(priv->volume_monitor);
+    g_ptr_array_unref(priv->repos);
+
+    G_OBJECT_CLASS(dnf_repo_loader_parent_class)->finalize(object);
+}
+
 /**
  * dnf_repo_loader_init:
  **/
@@ -525,20 +546,6 @@ dnf_repo_loader_get_repo_by_id(DnfRepoLoader *self, const gchar *id, GError **er
     return NULL;
 } CATCH_TO_GERROR(NULL)
 
-/**
- * dnf_repo_loader_directory_changed_cb:
- **/
-static void
-dnf_repo_loader_directory_changed_cb(GFileMonitor *monitor_,
-                                     GFile *file, GFile *other_file,
-                                     GFileMonitorEvent event_type,
-                                     DnfRepoLoader *self)
-{
-    g_debug("emit changed(ReposDir changed)");
-    g_signal_emit(self, signals[SIGNAL_CHANGED], 0);
-    dnf_repo_loader_invalidate(self);
-}
-
 /**
  * dnf_repo_loader_setup_monitor:
  */
