gnucash stable: Bug 799528 - Crash on account deletion (edit)

John Ralls jralls at code.gnucash.org
Tue Mar 4 15:03:55 EST 2025


Updated	 via  https://github.com/Gnucash/gnucash/commit/bc7fafd4 (commit)
	from  https://github.com/Gnucash/gnucash/commit/f3b08dde (commit)



commit bc7fafd4ad331b5afd46775ffcf7ae172dc41bb1
Author: John Ralls <jralls at ceridwen.us>
Date:   Tue Mar 4 11:57:17 2025 -0800

    Bug 799528 - Crash on account deletion (edit)
    
    New function xaccAccountDeleteAllTransactions.
    
    Delete all transactions before deleting the account; simply deleting the
    splits during account destruction isn't safe. In the particular case of an
    imbalance account the transaction commit after deleting a split just makes
    a new one.

diff --git a/gnucash/gnome/gnc-plugin-page-account-tree.cpp b/gnucash/gnome/gnc-plugin-page-account-tree.cpp
index 1321b9b30e..515173aa36 100644
--- a/gnucash/gnome/gnc-plugin-page-account-tree.cpp
+++ b/gnucash/gnome/gnc-plugin-page-account-tree.cpp
@@ -1694,11 +1694,22 @@ do_delete_account (Account* account, Account* saa, Account* sta, Account* ta)
                                        (AccountCb)xaccAccountMoveAllSplits,
                                        sta);
     }
+    else
+    {
+        gnc_account_foreach_descendant (account,
+                                        [](auto acc, [[maybe_unused]] auto data)
+                                        { xaccAccountDestroyAllTransactions(acc); },
+                                        nullptr);
+    }
     if (ta)
     {
         /* Move the splits of the account to be deleted. */
         xaccAccountMoveAllSplits (account, ta);
     }
+    else
+    {
+        xaccAccountDestroyAllTransactions (account);
+    }
     xaccAccountCommitEdit (account);
 
     /* Drop all references from the state file for
diff --git a/libgnucash/engine/Account.cpp b/libgnucash/engine/Account.cpp
index 438a0d8d04..8437e8f887 100644
--- a/libgnucash/engine/Account.cpp
+++ b/libgnucash/engine/Account.cpp
@@ -49,6 +49,7 @@
 #include <numeric>
 #include <map>
 #include <unordered_set>
+#include <algorithm>
 
 static QofLogModule log_module = GNC_MOD_ACCOUNT;
 
@@ -1596,6 +1597,18 @@ xaccAccountDestroy (Account *acc)
     xaccAccountCommitEdit (acc);
 }
 
+void
+xaccAccountDestroyAllTransactions(Account *acc)
+{
+    auto priv = GET_PRIVATE(acc);
+    std::vector<Transaction*> transactions;
+    std::transform(priv->splits.begin(), priv->splits.end(),
+                   back_inserter(transactions),
+                   [](auto split) { return split->parent; });
+    std::for_each(transactions.rbegin(), transactions.rend(),
+                  [](auto trans) { xaccTransDestroy (trans); });
+}
+
 /********************************************************************\
 \********************************************************************/
 
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index eea91ac018..3adbd4d1b7 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -210,6 +210,10 @@ typedef enum
      *    (by calling xaccAccountBeginEdit()) before calling this routine.*/
     void xaccAccountDestroy (Account *account);
 
+    /** Destroy all of the transactions that parent splits in an account.
+     */
+    void xaccAccountDestroyAllTransactions(Account *acc);
+
     /** Compare two accounts for equality - this is a deep compare. */
     gboolean xaccAccountEqual(const Account *a, const Account* b,
                               gboolean check_guids);



Summary of changes:
 gnucash/gnome/gnc-plugin-page-account-tree.cpp | 11 +++++++++++
 libgnucash/engine/Account.cpp                  | 13 +++++++++++++
 libgnucash/engine/Account.h                    |  4 ++++
 3 files changed, 28 insertions(+)



More information about the gnucash-changes mailing list