treewide: Fix memory leaks from calls to relocate().
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 20 Apr 2023 02:54:12 +0000 (19:54 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 20 Apr 2023 02:54:12 +0000 (19:54 -0700)
These were all avoidable, and I got tired of seeing message from Address
Sanitizer about them.

src/language/commands/set.c
src/language/lexer/include-path.c
src/libpspp/message.c
src/libpspp/str.c
src/libpspp/str.h
src/ui/gui/builder-wrapper.c
src/ui/gui/builder-wrapper.h
src/ui/gui/help-menu.c
src/ui/gui/main.c
src/ui/gui/psppire-syntax-window.c
src/ui/gui/psppire-window.c

index 7998850127eff11c6a42bb1f74dbf6c2b30baeb2..5994228c7c004c32e5d42b723df5ae4cd4485a1f 100644 (file)
@@ -1253,7 +1253,11 @@ show_system (const struct dataset *ds UNUSED)
   add_row (table, N_("Version"), version);
   add_row (table, N_("Host System"), host_system);
   add_row (table, N_("Build System"), build_system);
-  add_row (table, N_("Locale Directory"), relocate (locale_dir));
+
+  char *allocated;
+  add_row (table, N_("Locale Directory"), relocate2 (locale_dir, &allocated));
+  free (allocated);
+
   add_row (table, N_("Compiler Version"),
 #ifdef __VERSION__
            __VERSION__
index 96870a5a9a3041785f10cb74e7052ff79c641b74..0c640917b21afeed865ff38aeec10688e7ae1e4f 100644 (file)
@@ -83,7 +83,7 @@ include_path_init__ (void)
   if (home != NULL)
     string_array_append_nocopy (&the_include_path,
                                 xasprintf ("%s/.pspp", home));
-  string_array_append (&the_include_path, relocate (PKGDATADIR));
+  string_array_append_nocopy (&the_include_path, relocate_clone (PKGDATADIR));
 
   string_array_clone (&default_include_path, &the_include_path);
 }
index 07cc270787bab365b6b2a5f4e7d568e8ceeb0d3c..9b20a2350d9c7e21be0a0790917f0a20e658c62a 100644 (file)
@@ -638,10 +638,12 @@ prepare_fatal_error_message (void)
 const char *
 prepare_diagnostic_information (void)
 {
+  char *allocated;
+
   diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "version:             %s\n", version);
   diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "host_system:         %s\n", host_system);
   diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "build_system:        %s\n", build_system);
-  diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "locale_dir:          %s\n", relocate (locale_dir));
+  diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "locale_dir:          %s\n", relocate2 (locale_dir, &allocated));
   diagnostic_information_bytes += append_message (diagnostic_information, diagnostic_information_bytes, "compiler version:    %s\n",
 #ifdef __VERSION__
            __VERSION__
@@ -650,6 +652,8 @@ prepare_diagnostic_information (void)
 #endif
 );
 
+  free (allocated);
+
   return diagnostic_information;
 }
 
index 9cd6351e8d9d1dfdf67f1841b94233abad448f5e..f85844076bc7a2833f3674feecd5eee2d67408f4 100644 (file)
@@ -1749,7 +1749,30 @@ ds_relocate (struct string *st)
     }
 }
 
+/* Returns a relocated version of S as a malloc()'d string that the caller must
+   eventually free(). */
+char *
+relocate_clone (const char *s)
+{
+  char *r = CONST_CAST (char *, relocate (s));
+  return r != s ? r : xstrdup (s);
+}
 
+/* Formats FORMAT in a printf()-like manner and returns a relocated version of
+   it.  The caller must eventually free() the returned string. */
+char * PRINTF_FORMAT (1, 2) MALLOC_LIKE
+relocate_format (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  char *s = xvasprintf (format, args);
+  va_end (args);
+
+  char *r = CONST_CAST (char *, relocate (s));
+  if (r != s)
+    free (s);
+  return r;
+}
 \f
 
 /* Operations on uint8_t "strings" */
index 17584f8920ecea5116dde25d127b925f9242c7fb..77ba625decd2b0a15a0edd8a17a3dbd97186e06e 100644 (file)
@@ -262,7 +262,9 @@ char *ds_splice_uninit (struct string *, size_t ofs, size_t old_len,
 /* Other */
 /* calls relocate from gnulib on ST */
 void ds_relocate (struct string *st);
-
+char *relocate_clone (const char *);
+char *relocate_format (const char *, ...)
+  PRINTF_FORMAT (1, 2) MALLOC_LIKE;
 
 void u8_buf_copy_rpad (uint8_t *dst, size_t dst_size,
                       const uint8_t *src, size_t src_size,
index f856b3e87a7cb9855ccf92afe7795a3830c3e9d5..2f3cbdf9cf6d99aa76e23465d2fba92745f91b3c 100644 (file)
 
 #include "builder-wrapper.h"
 
+#include "libpspp/str.h"
 
-GtkBuilder *
+
+static GtkBuilder *
 builder_new_real (const gchar *name)
 {
   GtkBuilder *builder = gtk_builder_new ();
@@ -36,6 +38,16 @@ builder_new_real (const gchar *name)
   return builder;
 }
 
+GtkBuilder *
+builder_new (const gchar *name)
+{
+  char *full_name = relocate_format ("%s/%s", PKGDATADIR, name);
+  GtkBuilder *builder = builder_new_real (full_name);
+  free (full_name);
+
+  return builder;
+}
+
 GObject *
 get_object_assert (GtkBuilder *builder, const gchar *name, GType type)
 {
index db45168f32b98d3981e097b7a08665222e74442c..755ddcd9cf1ad74d43c6d9150d6afb0f9413f3e1 100644 (file)
@@ -23,9 +23,7 @@
 #include "relocatable.h"
 #include "gl/configmake.h"
 
-GtkBuilder *builder_new_real (const gchar *name);
-
-#define builder_new(NAME) (builder_new_real (relocate (PKGDATADIR "/" NAME)))
+GtkBuilder *builder_new (const gchar *name);
 
 GObject *get_object_assert (GtkBuilder *builder, const gchar *name, GType type);
 GtkWidget * get_widget_assert (GtkBuilder *builder, const gchar *name);
index 403e5950581eaf01d2536620fa8e03b2edb1f4c5..646c47a38367af870b2cc81ca5ff793edfaeedb7 100644 (file)
@@ -194,14 +194,11 @@ void
 online_help (const char *page)
 {
   GError *htmlerr = NULL;
-  gchar *htmlfilename = NULL;
-  gchar *htmlfullname = NULL;
   gchar *htmluri = NULL;
 
+  char *htmlfilename;
   if (page == NULL)
-    {
-      htmlfilename = g_strdup ("index.html");
-    }
+    htmlfilename = xstrdup ("index.html");
   else
     {
       gchar **tokens = NULL;
@@ -215,13 +212,13 @@ online_help (const char *page)
       tokens = g_strsplit (page, "#", maxtokens);
       for (idx = 0; idx < maxtokens && tokens[idx]; idx++)
        ;
-      htmlfilename = g_strdup_printf ("%s.html", tokens[idx-1]);
+      htmlfilename = xasprintf ("%s.html", tokens[idx-1]);
       g_strfreev (tokens);
     }
   /* Hint: pspp.html is a directory...*/
-  htmlfullname = g_strdup_printf ("%s/%s", relocate (DOCDIR "/pspp.html"),
-                                  htmlfilename);
-  if (g_file_test (relocate (DOCDIR "/pspp.html"), G_FILE_TEST_IS_DIR))
+  char *htmldir = relocate_clone (DOCDIR "/pspp.html");
+  char *htmlfullname = xasprintf ("%s/%s", htmldir, htmlfilename);
+  if (g_file_test (htmldir, G_FILE_TEST_IS_DIR))
     {
       GError *urierr = NULL;
       htmluri =  g_filename_to_uri (htmlfullname,NULL, &urierr);
@@ -235,8 +232,9 @@ online_help (const char *page)
   else
     htmluri = g_strdup_printf (PACKAGE_URL "manual/html_node/%s",
                                htmlfilename);
-  g_free (htmlfullname);
-  g_free (htmlfilename);
+  free (htmlfullname);
+  free (htmldir);
+  free (htmlfilename);
 
 #ifdef _WIN32
   bool ok = open_windows_help (htmluri, &htmlerr);
index 3241877d8509323711e0b5fce500c2a3402ca607..e7c917ad41453c9923a266469ed06a27edf1b536 100644 (file)
@@ -107,11 +107,9 @@ create_splash_window (void)
 {
   GtkWidget *sp = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
-  const gchar *filename = PKGDATADIR "/splash.png";
-  const char *relocated_filename = relocate (filename);
-  GtkWidget *l = gtk_image_new_from_file (relocated_filename);
-  if (filename != relocated_filename)
-    free (CONST_CAST (char *, relocated_filename));
+  char *splash = relocate_clone (PKGDATADIR"/splash.png");
+  GtkWidget *l = gtk_image_new_from_file (splash);
+  free (splash);
 
   gtk_container_add (GTK_CONTAINER (sp), l);
   gtk_window_set_type_hint (GTK_WINDOW (sp),
index 393c2afb5a0d966f3c5d8824601e760a73b4a709..3da9bf58f7b57722a206e55164252008fb3932c4 100644 (file)
@@ -157,9 +157,11 @@ psppire_syntax_window_class_init (PsppireSyntaxWindowClass *class)
   gchar **new_paths = g_strdupv ((gchar **)existing_paths);
   int n = g_strv_length ((gchar **) existing_paths);
 
+  char *pkg_data_dir = relocate_clone (PKGDATADIR);
   new_paths = g_realloc (new_paths, (n + 2) * sizeof (*new_paths));
-  new_paths[n] = g_strdup (relocate (PKGDATADIR));
+  new_paths[n] = g_strdup (pkg_data_dir);
   new_paths[n+1] = NULL;
+  free (pkg_data_dir);
 
   lm = gtk_source_language_manager_new ();
   gtk_source_language_manager_set_search_path (lm, new_paths);
index 60f265e4437a85a3feebdfc599091d2a8e702207..b636aa18e41d7c73bfb0fb5c62bdb60f6ca21a90 100644 (file)
@@ -718,7 +718,9 @@ psppire_window_open (PsppireWindow *de)
 {
   GtkWidget *dialog = psppire_window_file_chooser_dialog (de);
 
-  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), relocate (examples_dir), NULL);
+  char *dir = relocate_clone (examples_dir);
+  gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), dir, NULL);
+  free (dir);
 
   switch (gtk_dialog_run (GTK_DIALOG (dialog)))
     {