Blob Blame History Raw
From 323d0c7658a9a44efc327840c0667044a4b98f89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <sebastian@centricular.com>
Date: Mon, 3 Feb 2020 15:38:28 +0200
Subject: [PATCH 2/5] GMainContext - Fix GSource iterator if iteration can
 modify the list

We first have to ref the next source and then unref the previous one.
This might be the last reference to the previous source, and freeing the
previous source might unref and free the next one which would then leave
use with a dangling pointer here.

Fixes https://gitlab.gnome.org/GNOME/glib/issues/2031
---
 glib/gmain.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/glib/gmain.c b/glib/gmain.c
index 5b91c3117..a3ea1d36c 100644
--- a/glib/gmain.c
+++ b/glib/gmain.c
@@ -965,13 +965,17 @@ g_source_iter_next (GSourceIter *iter, GSource **source)
    * GSourceList to be removed from source_lists (if iter->source is
    * the only source in its list, and it is destroyed), so we have to
    * keep it reffed until after we advance iter->current_list, above.
+   *
+   * Also we first have to ref the next source before unreffing the
+   * previous one as unreffing the previous source can potentially
+   * free the next one.
    */
+  if (next_source && iter->may_modify)
+    g_source_ref (next_source);
 
   if (iter->source && iter->may_modify)
     g_source_unref_internal (iter->source, iter->context, TRUE);
   iter->source = next_source;
-  if (iter->source && iter->may_modify)
-    g_source_ref (iter->source);
 
   *source = iter->source;
   return *source != NULL;
-- 
2.31.1