gnucash stable: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Mon Feb 19 17:33:53 EST 2024


Updated	 via  https://github.com/Gnucash/gnucash/commit/4dbf8030 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fd150243 (commit)
	from  https://github.com/Gnucash/gnucash/commit/5cc14d82 (commit)



commit 4dbf8030411a1e2287be6e939336668e10f4a03a
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon Feb 19 14:31:12 2024 -0800

    Fix two use-after-free issues found by address sanitizer.

diff --git a/libgnucash/engine/Split.cpp b/libgnucash/engine/Split.cpp
index 2da0c51b9f..f481a57df0 100644
--- a/libgnucash/engine/Split.cpp
+++ b/libgnucash/engine/Split.cpp
@@ -706,7 +706,13 @@ xaccFreeSplit (Split *split)
     }
     CACHE_REMOVE(split->memo);
     CACHE_REMOVE(split->action);
-
+    if (GNC_IS_ACCOUNT (split->acc) && !qof_instance_get_destroying (QOF_INSTANCE (split->acc)))
+        gnc_account_remove_split (split->acc, split);
+    if (GNC_IS_LOT (split->lot) && !qof_instance_get_destroying (QOF_INSTANCE (split->lot)))
+        gnc_lot_remove_split (split->lot, split);
+/* We should do the same for split->parent but we might be getting
+ * called from xaccFreeTransactiob abd tgat would cause trouble.
+ */
     /* Just in case someone looks up freed memory ... */
     split->memo        = (char *) 1;
     split->action      = NULL;
diff --git a/libgnucash/engine/Transaction.cpp b/libgnucash/engine/Transaction.cpp
index 899adaa9d0..0ac8b346c4 100644
--- a/libgnucash/engine/Transaction.cpp
+++ b/libgnucash/engine/Transaction.cpp
@@ -1509,7 +1509,11 @@ do_destroy (Transaction *trans)
        done for the next split, then a split will still be on the split list after it
        has been freed.  This can cause other parts of the code (e.g. in xaccSplitDestroy())
        to reference the split after it has been freed. */
-    for (node = trans->splits; node; node = node->next)
+
+    auto splits = trans->splits;
+    trans->splits = NULL;
+
+    for (node = splits; node; node = node->next)
     {
         Split *s = GNC_SPLIT(node->data);
         if (s && s->parent == trans)
@@ -1517,7 +1521,7 @@ do_destroy (Transaction *trans)
             xaccSplitDestroy(s);
         }
     }
-    for (node = trans->splits; node; node = node->next)
+    for (node = splits; node; node = node->next)
     {
         Split *s = GNC_SPLIT(node->data);
         if (s && s->parent == trans)
@@ -1526,7 +1530,6 @@ do_destroy (Transaction *trans)
         }
     }
     g_list_free (trans->splits);
-    trans->splits = NULL;
     xaccFreeTransaction (trans);
 }
 

commit fd150243ef40ce11aace5a17017209d01f0a22d2
Author: John Ralls <jralls at ceridwen.us>
Date:   Sun Feb 18 16:36:24 2024 -0800

    Bug 799222 - Crash when changing the parent of an account that has...
    
    had two or more levels of sub-accounts auto-created using the register
    in the current session.
    
    Ensure removal of dangling signal handler when the dialog is destroyed.

diff --git a/gnucash/gnome-utils/dialog-account.c b/gnucash/gnome-utils/dialog-account.c
index 0bd2e8566f..41b2832f22 100644
--- a/gnucash/gnome-utils/dialog-account.c
+++ b/gnucash/gnome-utils/dialog-account.c
@@ -129,6 +129,9 @@ typedef struct _AccountWindow
     GtkWidget *auto_interest_button;
 
     gint component_id;
+
+    GObject *selection;
+    gulong handler_id;
 } AccountWindow;
 
 typedef struct _RenumberDialog
@@ -161,7 +164,7 @@ void gnc_account_renumber_response_cb (GtkDialog *dialog, gint response, Renumbe
 
 void gnc_account_window_destroy_cb (GtkWidget *object, gpointer data);
 void opening_equity_cb (GtkWidget *w, gpointer data);
-static void gnc_account_parent_changed_cb (GtkTreeSelection *selection, gpointer data);
+static void gnc_account_parent_changed_cb (GObject *selection, gpointer data);
 void gnc_account_name_changed_cb (GtkWidget *widget, gpointer data);
 void gnc_account_color_default_cb (GtkWidget *widget, gpointer data);
 void gnc_account_name_insert_text_cb (GtkWidget   *entry,
@@ -170,6 +173,11 @@ void gnc_account_name_insert_text_cb (GtkWidget   *entry,
                                       gint        *position,
                                       gpointer     data);
 static void set_auto_interest_box (AccountWindow *aw);
+static gboolean account_commodity_filter (GtkTreeSelection* selection,
+                                          GtkTreeModel* unused_model,
+                                          GtkTreePath* s_path,
+                                          gboolean path_currently_selected,
+                                          gpointer user_data);
 
 /** Implementation *******************************************************/
 
@@ -195,6 +203,25 @@ aw_get_account (AccountWindow *aw)
     return xaccAccountLookup (&aw->account, aw->book);
 }
 
+static void
+aw_clear_selection_handler (AccountWindow *aw)
+{
+    if (aw->selection && aw->handler_id)
+        g_signal_handler_disconnect (aw->selection, aw->handler_id);
+    aw->selection = NULL;
+    aw->handler_id = 0;
+}
+
+static void
+aw_connect_selection_changed (AccountWindow *aw)
+{
+    aw_clear_selection_handler (aw);
+    aw->selection = G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW(aw->parent_tree)));
+    aw->handler_id = g_signal_connect (G_OBJECT(aw->selection), "changed",
+                                       G_CALLBACK(gnc_account_parent_changed_cb),
+                                       aw);
+}
+
 static void
 gnc_account_commodity_from_type (AccountWindow * aw, gboolean update)
 {
@@ -713,7 +740,6 @@ gnc_finish_ok (AccountWindow *aw)
         gnc_commodity *commodity;
         Account *parent;
         Account *account;
-        GtkTreeSelection *selection;
 
         /* Drop the old parent_tree so we can update it with an up to date one */
         gtk_container_remove (GTK_CONTAINER(aw->parent_scroll), GTK_WIDGET(aw->parent_tree));
@@ -721,10 +747,7 @@ gnc_finish_ok (AccountWindow *aw)
         gtk_container_add (GTK_CONTAINER(aw->parent_scroll), GTK_WIDGET(aw->parent_tree));
         gtk_widget_show (GTK_WIDGET(aw->parent_tree));
 
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(aw->parent_tree));
-        g_signal_connect (G_OBJECT(selection), "changed",
-                          G_CALLBACK(gnc_account_parent_changed_cb), aw);
-
+        aw_connect_selection_changed (aw);
         gnc_suspend_gui_refresh ();
 
         parent = aw_get_account (aw);
@@ -1173,6 +1196,7 @@ gnc_account_window_destroy_cb (GtkWidget *object, gpointer data)
     ENTER("object %p, aw %p", object, aw);
     account = aw_get_account (aw);
 
+    aw_clear_selection_handler (aw);
     gnc_suspend_gui_refresh ();
 
     switch (aw->dialog_type)
@@ -1214,7 +1238,7 @@ gnc_account_window_destroy_cb (GtkWidget *object, gpointer data)
 }
 
 static void
-gnc_account_parent_changed_cb (GtkTreeSelection *selection, gpointer data)
+gnc_account_parent_changed_cb (GObject *selection, gpointer data)
 {
     AccountWindow *aw = data;
     Account *parent_account;
@@ -1224,6 +1248,7 @@ gnc_account_parent_changed_cb (GtkTreeSelection *selection, gpointer data)
     gboolean combo_set = FALSE;
 
     g_return_if_fail (aw);
+    g_return_if_fail (selection == aw->selection);
 
     parent_account = gnc_tree_view_account_get_selected_account (
                          GNC_TREE_VIEW_ACCOUNT(aw->parent_tree));
@@ -1608,10 +1633,7 @@ gnc_account_window_create (GtkWindow *parent, AccountWindow *aw)
     aw->parent_tree = gnc_tree_view_account_new (TRUE);
     gtk_container_add (GTK_CONTAINER(aw->parent_scroll), GTK_WIDGET(aw->parent_tree));
     gtk_widget_show (GTK_WIDGET(aw->parent_tree));
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(aw->parent_tree));
-
-    g_signal_connect (G_OBJECT(selection), "changed",
-                      G_CALLBACK(gnc_account_parent_changed_cb), aw);
+    aw_connect_selection_changed (aw);
 
     aw->balance_grid = GTK_WIDGET(gtk_builder_get_object (builder, "balance_grid"));
 



Summary of changes:
 gnucash/gnome-utils/dialog-account.c | 44 +++++++++++++++++++++++++++---------
 libgnucash/engine/Split.cpp          |  8 ++++++-
 libgnucash/engine/Transaction.cpp    |  9 +++++---
 3 files changed, 46 insertions(+), 15 deletions(-)



More information about the gnucash-changes mailing list