From c091197f572a701cb2ecc81c40fe47bbd41f59aa Mon Sep 17 00:00:00 2001 From: John Ralls Date: Thu, 11 Apr 2019 17:25:40 -0700 Subject: [PATCH] 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. --- libgnucash/core-utils/gnc-filepath-utils.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libgnucash/core-utils/gnc-filepath-utils.cpp b/libgnucash/core-utils/gnc-filepath-utils.cpp index 29eedfcb95..ac46d4227d 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&