gnucash maint: Provide static strings for gnc_userdata_home and gnc_userconfig_home.

John Ralls jralls at code.gnucash.org
Thu Apr 11 20:38:35 EDT 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/c091197f (commit)
	from  https://github.com/Gnucash/gnucash/commit/6e7a4ccc (commit)



commit c091197f572a701cb2ecc81c40fe47bbd41f59aa
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Apr 11 17:25:40 2019 -0700

    Provide static strings for gnc_userdata_home and gnc_userconfig_home.
    
    On Windows boost::filesystem::path's string() produces a string
    that goes out of scope with the function in which it's called, so
    returning its c_str() ptr yields freed memory, usually full of garbage.
    
    This has an interesting side effect in gnc-file.c's check_file_path():
    Since the memory is freed, g_path_get_dirname() reuses it after an
    iteration or two, writing its result into the same address. The
    following strcmp naturally returns 0 because it's comparing two
    instances of the same ptr, so check_file_path falsely reports that
    the proposed save path is in GNC_USERDATA_DIR.

diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp
index 29eedfcb9..ac46d4227 100644
--- a/libgnucash/core-utils/gnc-filepath-utils.cpp
+++ b/libgnucash/core-utils/gnc-filepath-utils.cpp
@@ -334,6 +334,12 @@ gnc_path_find_localized_html_file (const gchar *file_name)
 static auto gnc_userdata_home = bfs::path();
 static auto gnc_userconfig_home = bfs::path();
 static auto build_dir = bfs::path();
+/*Provide static-stored strings for gnc_userdata_home and
+ * gnc_userconfig_home to ensure that the cstrings don't go out of
+ * scope when gnc_userdata_dir and gnc_userconfig_dir return them.
+ */
+static std::string gnc_userdata_home_str;
+static std::string gnc_userconfig_home_str;
 
 static bool dir_is_descendant (const bfs::path& path, const bfs::path& base)
 {
@@ -458,7 +464,7 @@ copy_recursive(const bfs::path& src, const bfs::path& dest)
     {
         g_warning("An error occured while trying to migrate the user configation from\n%s to\n%s"
                   "(Error: %s)",
-                  src.string().c_str(), gnc_userdata_home.string().c_str(),
+                  src.string().c_str(), gnc_userdata_home_str.c_str(),
                   ex.what());
         return false;
     }
@@ -808,6 +814,7 @@ gnc_file_path_init_config_home (void)
             "(Error: %s)", ex.what());
         }
     }
+    gnc_userconfig_home_str = gnc_userconfig_home.string();
 }
 
 // Initialize the user's config directory for gnucash
@@ -891,7 +898,7 @@ gnc_file_path_init_data_home (void)
             "(Error: %s)", ex.what());
         }
     }
-
+    gnc_userdata_home_str = gnc_userdata_home.string();
     return gnc_userdata_home_exists;
 }
 
@@ -907,6 +914,7 @@ char *
 gnc_filepath_init (void)
 {
     gnc_userconfig_home = get_userconfig_home() / path_package;
+    gnc_userconfig_home_str = gnc_userconfig_home.string();
 
     gnc_file_path_init_config_home ();
     auto gnc_userdata_home_exists = gnc_file_path_init_data_home ();
@@ -976,8 +984,7 @@ gnc_userdata_dir (void)
 {
     if (gnc_userdata_home.empty())
         gnc_filepath_init();
-
-    return gnc_userdata_home.string().c_str();
+    return g_strdup(gnc_userdata_home_str.c_str());
 }
 
 /** @fn const gchar * gnc_userconfig_dir ()
@@ -999,7 +1006,7 @@ gnc_userconfig_dir (void)
     if (gnc_userdata_home.empty())
         gnc_filepath_init();
 
-    return gnc_userconfig_home.string().c_str();
+    return gnc_userconfig_home_str.c_str();
 }
 
 static const bfs::path&



Summary of changes:
 libgnucash/core-utils/gnc-filepath-utils.cpp | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)



More information about the gnucash-changes mailing list