gnucash stable: Multiple changes pushed

Christopher Lam clam at code.gnucash.org
Sun Apr 19 18:43:10 EDT 2026


Updated	 via  https://github.com/Gnucash/gnucash/commit/2e360ae0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1ea22be0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/fbcdfb0a (commit)
	from  https://github.com/Gnucash/gnucash/commit/15510b7f (commit)



commit 2e360ae05fe07ae02b46bb7d576fd9dd2b171ecf
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Apr 20 00:44:55 2026 +0800

    [window-main-summarybar.c] g_free a char*
    
    which would leak when the pref general/negative-in-red preference
    is toggled

diff --git a/gnucash/gnome-utils/window-main-summarybar.c b/gnucash/gnome-utils/window-main-summarybar.c
index 66db9d37fa..64d641b375 100644
--- a/gnucash/gnome-utils/window-main-summarybar.c
+++ b/gnucash/gnome-utils/window-main-summarybar.c
@@ -465,6 +465,7 @@ summarybar_update_color (gpointer gsettings, gchar *key, gpointer user_data)
 {
     GNCMainSummary *summary = user_data;
 
+    g_free(summary->negative_color);
     summary->negative_color = get_negative_color_str();
     summary->show_negative_color = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
 

commit 1ea22be0eafeb2d95eb06d48caa0d72c51cc7e6b
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Apr 20 05:28:35 2026 +0800

    [gnc-plugin-report-system] use g_markup_printf_escaped for safe html
    
    instead of manual function

diff --git a/gnucash/gnome/gnc-plugin-report-system.c b/gnucash/gnome/gnc-plugin-report-system.c
index aaf64f7b4a..5cbf4e16f0 100644
--- a/gnucash/gnome/gnc-plugin-report-system.c
+++ b/gnucash/gnome/gnc-plugin-report-system.c
@@ -128,25 +128,6 @@ gnc_report_system_file_stream_cb (const char *location, char ** data, int *len)
     return (*len > 0);
 }
 
-static char *
-html_sanitize (const char *str)
-{
-    g_return_val_if_fail (str, NULL);
-    GString *gs = g_string_sized_new (strlen (str));
-    for (const char *c = str; *c; c++)
-    {
-        if (*c == '&')
-            gs = g_string_append (gs, "&");
-        else if (*c == '<')
-            gs = g_string_append (gs, "<");
-        else if (*c == '>')
-            gs = g_string_append (gs, ">");
-        else
-            gs = g_string_append_c (gs, *c);
-    }
-    return g_string_free (gs, FALSE);
-}
-
 static gboolean
 gnc_report_system_report_stream_cb (const char *location, char ** data, int *len)
 {
@@ -157,14 +138,12 @@ gnc_report_system_report_stream_cb (const char *location, char ** data, int *len
 
     if (!ok)
     {
-        char *sanitized = html_sanitize (captured_str);
-        *data = g_strdup_printf ("<html><body><h3>%s</h3>"
-                                 "<p>%s</p><pre>%s</pre></body></html>",
-                                 _("Report error"),
-                                 _("An error occurred while running the report."),
-                                 sanitized);
-
-        g_free (sanitized);
+        *data = g_markup_printf_escaped ("<html><body><h3>%s</h3>"
+                                         "<p>%s</p><pre>%s</pre></body></html>",
+                                         _("Report error"),
+                                         _("An error occurred while running the report."),
+                                         captured_str);
+
         g_free(captured_str);
 
         /* Make sure the progress bar is finished, which will also

commit fbcdfb0a54e94506e41212e29f076624955664ab
Author: Christopher Lam <christopher.lck at gmail.com>
Date:   Mon Apr 20 05:29:12 2026 +0800

    [window-main-summarybar.c] use g_markup_printf_escaped for safe html
    
    instead of a manual function

diff --git a/gnucash/gnome-utils/window-main-summarybar.c b/gnucash/gnome-utils/window-main-summarybar.c
index 44708becc7..66db9d37fa 100644
--- a/gnucash/gnome-utils/window-main-summarybar.c
+++ b/gnucash/gnome-utils/window-main-summarybar.c
@@ -498,48 +498,23 @@ prefs_changed_cb (gpointer prefs, gchar *pref, gpointer user_data)
     gnc_main_window_summary_refresh(summary);
 }
 
-static gchar*
-check_string_for_markup (gchar *string)
-{
-    gchar **strings;
-    gchar *ret_string = g_strdup (string);
 
-    if (g_strrstr (ret_string, "&") != NULL)
-    {
-        strings = g_strsplit (ret_string, "&", -1);
-        g_free (ret_string);
-        ret_string = g_strjoinv ("&", strings);
-        g_strfreev (strings);
-    }
-    if (g_strrstr (ret_string, "<") != NULL)
-    {
-        strings = g_strsplit (ret_string, "<", -1);
-        g_free (ret_string);
-        ret_string = g_strjoinv ("<", strings);
-        g_strfreev (strings);
-    }
-    if (g_strrstr (ret_string, ">") != NULL)
-    {
-        strings = g_strsplit (ret_string, ">", -1);
-        g_free (ret_string);
-        ret_string = g_strjoinv (">", strings);
-        g_strfreev (strings);
-    }
-    if (g_strrstr (ret_string, "\"") != NULL)
-    {
-        strings = g_strsplit (ret_string, "\"", -1);
-        g_free (ret_string);
-        ret_string = g_strjoinv (""", strings);
-        g_strfreev (strings);
-    }
-    if (g_strrstr (ret_string, "'") != NULL)
-    {
-        strings = g_strsplit (ret_string, "'", -1);
-        g_free (ret_string);
-        ret_string = g_strjoinv ("'", strings);
-        g_strfreev (strings);
-    }
-    return ret_string;
+static gchar *
+make_markup (GtkTreeModel *model, GtkTreeIter *iter,
+             const GNCMainSummary *summary,
+             gint label_col, gint value_col, gint neg_col)
+{
+    gchar *label, *value;
+    gboolean neg;
+    gtk_tree_model_get (model, iter, label_col, &label, value_col, &value, neg_col, &neg,
+                        -1);
+    gchar* markup = summary->show_negative_color && neg
+        ? g_markup_printf_escaped ("%s <span foreground='%s'>%s</span>",
+                                   label, summary->negative_color, value)
+        : g_markup_printf_escaped ("%s %s", label, value);
+    g_free (label);
+    g_free (value);
+    return markup;
 }
 
 static void
@@ -547,8 +522,6 @@ cdf (GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *tree_model
                           gpointer user_data)
 {
     GNCMainSummary * summary = user_data;
-    gchar *type, *assets, *assets_val, *profits, *profits_val;
-    gboolean assets_neg, profits_neg;
     gint viewcol;
 
     viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "view_column"));
@@ -558,49 +531,31 @@ cdf (GtkCellLayout *cell_layout, GtkCellRenderer *cell, GtkTreeModel *tree_model
     else
         g_object_set (cell, "xalign", 0.5, NULL);
 
-    gtk_tree_model_get (GTK_TREE_MODEL (tree_model), iter,
-                            COLUMN_MNEMONIC_TYPE, &type,
-                            COLUMN_ASSETS, &assets,
-                            COLUMN_ASSETS_VALUE, &assets_val,
-                            COLUMN_PROFITS, &profits,
-                            COLUMN_PROFITS_VALUE, &profits_val,
-                            COLUMN_ASSETS_NEG, &assets_neg,
-                            COLUMN_PROFITS_NEG, &profits_neg, -1);
-
     if (viewcol == 0)
+    {
+        gchar *type;
+        gtk_tree_model_get (GTK_TREE_MODEL (tree_model), iter,
+                            COLUMN_MNEMONIC_TYPE, &type,
+                            -1);
         g_object_set (cell, "text", type, NULL);
+        g_free (type);
+    }
 
     if (viewcol == 2)
     {
-        gchar *a_string, *checked_string = check_string_for_markup (assets_val);
-        if ((summary->show_negative_color == TRUE) && (assets_neg == TRUE))
-            a_string = g_strconcat (assets, " <span foreground='", summary->negative_color, "'>", checked_string, "</span>", NULL);
-        else
-            a_string = g_strconcat (assets, " ", checked_string, NULL);
-
-        g_object_set (cell, "markup", a_string, NULL);
-        g_free (a_string);
-        g_free (checked_string);
+        gchar *markup = make_markup (tree_model, iter, summary,
+                                     COLUMN_ASSETS, COLUMN_ASSETS_VALUE, COLUMN_ASSETS_NEG);
+        g_object_set (cell, "markup", markup, NULL);
+        g_free (markup);
     }
 
     if (viewcol == 4)
     {
-        gchar *p_string, *checked_string = check_string_for_markup (profits_val);
-        if ((summary->show_negative_color == TRUE) && (profits_neg == TRUE))
-            p_string = g_strconcat (profits, " <span foreground='", summary->negative_color, "'>", checked_string, "</span>", NULL);
-        else
-            p_string = g_strconcat (profits, " ", checked_string, NULL);
-
-        g_object_set (cell, "markup", p_string, NULL);
-        g_free (p_string);
-        g_free (checked_string);
+        gchar *markup = make_markup (tree_model, iter, summary,
+                                     COLUMN_PROFITS, COLUMN_PROFITS_VALUE, COLUMN_PROFITS_NEG);
+        g_object_set (cell, "markup", markup, NULL);
+        g_free (markup);
     }
-
-    g_free (type);
-    g_free (assets);
-    g_free (assets_val);
-    g_free (profits);
-    g_free (profits_val);
 }
 
 static void



Summary of changes:
 gnucash/gnome-utils/window-main-summarybar.c | 108 ++++++++-------------------
 gnucash/gnome/gnc-plugin-report-system.c     |  33 ++------
 2 files changed, 38 insertions(+), 103 deletions(-)



More information about the gnucash-changes mailing list