]> granicus.if.org Git - graphviz/commitdiff
smyrna savefiledlg, on_gvprbuttonsave_clicked: fix memory leaks
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Mon, 10 Oct 2022 15:08:51 +0000 (08:08 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 15 Oct 2022 00:32:13 +0000 (17:32 -0700)
The `gtk_file_chooser_get_filename` docs¹ note:

  Return value
  …
  The currently selected filename, or NULL if no file is selected, or the
  selected file can’t be represented with a local filename. Free with g_free().

  The caller of the method takes ownership of the data, and is responsible for
  freeing it.

Contrary to this, `savefiledlg` was duplicating the pointed to data and then
losing the pointer `gtk_file_chooser_get_filename` returned.

The straightforward fix to this would be to retain the pointer and then `g_free`
it after copying its contents into the buffer `xbuf`. However, we can instead
refactor this function to avoid the copy altogether and simply pass the original
memory back to the caller, making this both a fix and an optimization.

On top of this, `on_gvprbuttonsave_clicked` was never calling `agxbfree` on its
local `xbuf`. By moving to a standard string, we also fix this memory leak.

¹ https://docs.gtk.org/gtk3/method.FileChooser.get_filename.html

cmd/smyrna/gui/gui.c
cmd/smyrna/gui/gui.h
cmd/smyrna/gui/menucallbacks.c

index 4c148f2987db1ed6ad71b9b482d999605d70f9c8..1b706c9eaca649eb1818d5f7078a4adb3afea127 100644 (file)
@@ -145,7 +145,9 @@ int openfiledlg(char **filename) {
     return rv;
 }
 
-int savefiledlg(agxbuf *xbuf) {
+int savefiledlg(char **filename) {
+    assert(filename != NULL);
+
     GtkWidget *dialog;
     int rv;
 
@@ -158,8 +160,7 @@ int savefiledlg(agxbuf *xbuf) {
                                         GTK_RESPONSE_ACCEPT, NULL);
 
     if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
-       agxbput(xbuf,
-               gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
+       *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
        rv = 1;
     } else
        rv = 0;
index f903caad4d669ab6ccfd3ef061d0fa014e5071d2..c0d44b8ba2cfa7fe123017a5789c2e113668f1fb 100644 (file)
@@ -17,7 +17,6 @@
 #include <glade/glade.h>
 #include "callbacks.h"
 #include <cgraph/cgraph.h>
-#include <cgraph/agxbuf.h>
 
 #define MAXIMUM_WIDGET_COUNT   97
 
  * \return Non-zero on success.
  */
     int openfiledlg(char **filename);
-/*generic save file dialog*/
-    int savefiledlg(agxbuf * xbuf);
+/** generic save file dialog
+ *
+ * \param [out] filename Selected filename on success. Caller should \p g_free
+ *   this.
+ * \return Non-zero on success.
+ */
+    int savefiledlg(char **filename);
     void append_textview(GtkTextView * textv, const char *s, size_t bytes);
index a9542c02fd12df0f66323ab335d1b5a73ea8e866..4e4e8b6eff1301395cf91daf05a4873db262c979 100644 (file)
@@ -396,15 +396,15 @@ void on_gvprbuttonsave_clicked(GtkWidget * widget, gpointer user_data)
     (void)user_data;
 
     FILE *output_file = NULL;
-    agxbuf xbuf = {0};
     GtkTextBuffer *gtkbuf;     /*GTK buffer from glade GUI */
     char *bf2;
     GtkTextIter startit;
     GtkTextIter endit;
 
-    /*file name should be returned in xbuf */
-    if (savefiledlg(&xbuf)) {
-       output_file = fopen(agxbuse(&xbuf), "w");
+    char *filename = NULL;
+    if (savefiledlg(&filename)) {
+       output_file = fopen(filename, "w");
+       g_free(filename);
        if (output_file) {
            gtkbuf =
                gtk_text_view_get_buffer((GtkTextView *)