From d0c6df12a42e2339d323048ff51ae25eea1a3c07 Mon Sep 17 00:00:00 2001
From: Adric Blake <promarbler14@gmail.com>
Date: Fri, 1 Sep 2023 21:30:19 -0400
Subject: [PATCH] Remove weak pointers on dispose

A weak pointer has a callback that will happily overwrite freed object memory if the weakly referenced object outlives the object storing the reference. Remove those callbacks when they are no longer needed.
---
 libmatemixer/matemixer-device-switch.c  | 17 +++++++++++++++++
 libmatemixer/matemixer-stream-control.c | 15 +++++++++++++++
 libmatemixer/matemixer-stream-switch.c  | 17 +++++++++++++++++
 libmatemixer/matemixer-stream.c         |  4 ++++
 4 files changed, 53 insertions(+)

diff --git a/libmatemixer/matemixer-device-switch.c b/libmatemixer/matemixer-device-switch.c
index 51e946e..a8fa18c 100644
--- a/libmatemixer/matemixer-device-switch.c
+++ b/libmatemixer/matemixer-device-switch.c
@@ -53,6 +53,8 @@ static void mate_mixer_device_switch_set_property (GObject                    *o
                                                    const GValue               *value,
                                                    GParamSpec                 *pspec);
 
+static void mate_mixer_device_switch_dispose      (GObject                    *object);
+
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MateMixerDeviceSwitch, mate_mixer_device_switch, MATE_MIXER_TYPE_SWITCH)
 
 static void
@@ -61,6 +63,7 @@ mate_mixer_device_switch_class_init (MateMixerDeviceSwitchClass *klass)
     GObjectClass *object_class;
 
     object_class = G_OBJECT_CLASS (klass);
+    object_class->dispose      = mate_mixer_device_switch_dispose;
     object_class->get_property = mate_mixer_device_switch_get_property;
     object_class->set_property = mate_mixer_device_switch_set_property;
 
@@ -143,6 +146,20 @@ mate_mixer_device_switch_init (MateMixerDeviceSwitch *swtch)
     swtch->priv = mate_mixer_device_switch_get_instance_private (swtch);
 }
 
+static void
+mate_mixer_device_switch_dispose (GObject *object)
+{
+    MateMixerDeviceSwitch *swtch;
+
+    swtch = MATE_MIXER_DEVICE_SWITCH (object);
+
+    if (swtch->priv->device != NULL)
+        g_object_remove_weak_pointer(G_OBJECT (swtch->priv->device),
+                                     (gpointer *) &swtch->priv->device);
+
+    G_OBJECT_CLASS (mate_mixer_device_switch_parent_class)->dispose (object);
+}
+
 /**
  * mate_mixer_device_switch_get_role:
  * @swtch: a #MateMixerDeviceSwitch
diff --git a/libmatemixer/matemixer-stream-control.c b/libmatemixer/matemixer-stream-control.c
index df02df1..fa1829a 100644
--- a/libmatemixer/matemixer-stream-control.c
+++ b/libmatemixer/matemixer-stream-control.c
@@ -75,6 +75,7 @@ static void mate_mixer_stream_control_set_property (GObject
                                                     const GValue                *value,
                                                     GParamSpec                  *pspec);
 
+static void mate_mixer_stream_control_dispose      (GObject                     *object);
 static void mate_mixer_stream_control_finalize     (GObject                     *object);
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MateMixerStreamControl, mate_mixer_stream_control, G_TYPE_OBJECT)
@@ -85,6 +86,7 @@ mate_mixer_stream_control_class_init (MateMixerStreamControlClass *klass)
     GObjectClass *object_class;
 
     object_class = G_OBJECT_CLASS (klass);
+    object_class->dispose      = mate_mixer_stream_control_dispose;
     object_class->finalize     = mate_mixer_stream_control_finalize;
     object_class->get_property = mate_mixer_stream_control_get_property;
     object_class->set_property = mate_mixer_stream_control_set_property;
@@ -284,6 +286,19 @@ mate_mixer_stream_control_init (MateMixerStreamControl *control)
     control->priv = mate_mixer_stream_control_get_instance_private (control);
 }
 
+static void
+mate_mixer_stream_control_dispose (GObject *object)
+{
+    MateMixerStreamControl *control;
+
+    control = MATE_MIXER_STREAM_CONTROL (object);
+    if (control->priv->stream != NULL)
+        g_object_remove_weak_pointer(G_OBJECT (control->priv->stream),
+                                     (gpointer *) &control->priv->stream);
+
+    G_OBJECT_CLASS (mate_mixer_stream_control_parent_class)->dispose (object);
+}
+
 static void
 mate_mixer_stream_control_finalize (GObject *object)
 {
diff --git a/libmatemixer/matemixer-stream-switch.c b/libmatemixer/matemixer-stream-switch.c
index 814918d..cfb74c8 100644
--- a/libmatemixer/matemixer-stream-switch.c
+++ b/libmatemixer/matemixer-stream-switch.c
@@ -55,6 +55,8 @@ static void mate_mixer_stream_switch_set_property (GObject                    *o
                                                    const GValue               *value,
                                                    GParamSpec                 *pspec);
 
+static void mate_mixer_stream_switch_dispose      (GObject                    *object);
+
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MateMixerStreamSwitch, mate_mixer_stream_switch, MATE_MIXER_TYPE_SWITCH)
 
 static void
@@ -63,6 +65,7 @@ mate_mixer_stream_switch_class_init (MateMixerStreamSwitchClass *klass)
     GObjectClass *object_class;
 
     object_class = G_OBJECT_CLASS (klass);
+    object_class->dispose      = mate_mixer_stream_switch_dispose;
     object_class->get_property = mate_mixer_stream_switch_get_property;
     object_class->set_property = mate_mixer_stream_switch_set_property;
 
@@ -161,6 +164,20 @@ mate_mixer_stream_switch_init (MateMixerStreamSwitch *swtch)
     swtch->priv = mate_mixer_stream_switch_get_instance_private (swtch);
 }
 
+static void
+mate_mixer_stream_switch_dispose (GObject *object)
+{
+    MateMixerStreamSwitch *swtch;
+
+    swtch = MATE_MIXER_STREAM_SWITCH (object);
+
+    if (swtch->priv->stream != NULL)
+        g_object_remove_weak_pointer(G_OBJECT (swtch->priv->stream),
+                                     (gpointer *) &swtch->priv->stream);
+
+    G_OBJECT_CLASS (mate_mixer_stream_switch_parent_class)->dispose (object);
+}
+
 /**
  * mate_mixer_stream_switch_get_flags:
  * @swtch: a #MateMixerStreamSwitch
diff --git a/libmatemixer/matemixer-stream.c b/libmatemixer/matemixer-stream.c
index ca7bc81..41da51b 100644
--- a/libmatemixer/matemixer-stream.c
+++ b/libmatemixer/matemixer-stream.c
@@ -281,6 +281,10 @@ mate_mixer_stream_dispose (GObject *object)
 
     stream = MATE_MIXER_STREAM (object);
 
+    if (stream->priv->device != NULL)
+        g_object_remove_weak_pointer (G_OBJECT (stream->priv->device),
+                                      (gpointer *) &stream->priv->device);
+
     g_clear_object (&stream->priv->control);
 
     G_OBJECT_CLASS (mate_mixer_stream_parent_class)->dispose (object);
