From 1789c96ae73720ef001249d2085553102043aee3 Mon Sep 17 00:00:00 2001
From: Mamoru TASAKA <mtasaka@fedoraproject.org>
Date: Thu, 28 Oct 2021 22:07:14 +0900
Subject: [PATCH] fm_config_load_from_key_file: don't replace string value when
 loaded config file does not have such key

For example, fm_config_load_from_file() loads every key file with path
ending with "/libfm/libfm.conf" under XDG_CONFIG_DIRS using fm_config_load_from_key_file().

With current fm_config_load_from_key_file() implementation, every time it is called,
for key having string, firstly the old value is always free'ed, and the new value is
read and set, even if the new value is empty.
So if system wide key file contains a key with string value but user-specific key file
does not contain the key, system widely set key value is lost, which is unwilling.

For other value types (such as bool or int), the corresponding fm_key_file_get_TYPE
function are used, and these functions replace old values when the new config file
actually has the corresponding key.

With this patch, similar to other value types, string value is to be replaced
only when new loaded config actually has corresponding key.
Also, implement fm_key_file_get_string() to be consistent with other types.
---
 src/base/fm-config.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/src/base/fm-config.c b/src/base/fm-config.c
index a633857..1e3d3f7 100644
--- a/src/base/fm-config.c
+++ b/src/base/fm-config.c
@@ -245,6 +245,19 @@ static void _parse_drop_default_action(GKeyFile *kf, gint *action)
     }
 }
 
+static gboolean fm_key_file_get_string(GKeyFile* kf, const char* grp, const char* key, char** val)
+{
+    char* str_key_new = g_key_file_get_string(kf, grp, key, NULL);
+    if(G_LIKELY(str_key_new))
+    {
+        if (*val)
+            g_free(*val);
+        *val = str_key_new;
+    }
+    return str_key_new != NULL;
+}
+
+
 /**
  * fm_config_load_from_key_file
  * @cfg: pointer to configuration
@@ -263,12 +276,8 @@ void fm_config_load_from_key_file(FmConfig* cfg, GKeyFile* kf)
     fm_key_file_get_int(kf, "config", "auto_selection_delay", &cfg->auto_selection_delay);
     fm_key_file_get_bool(kf, "config", "confirm_del", &cfg->confirm_del);
     fm_key_file_get_bool(kf, "config", "confirm_trash", &cfg->confirm_trash);
-    if(cfg->terminal)
-        g_free(cfg->terminal);
-    cfg->terminal = g_key_file_get_string(kf, "config", "terminal", NULL);
-    if(cfg->archiver)
-        g_free(cfg->archiver);
-    cfg->archiver = g_key_file_get_string(kf, "config", "archiver", NULL);
+    fm_key_file_get_string(kf, "config", "terminal", &cfg->terminal);
+    fm_key_file_get_string(kf, "config", "archiver", &cfg->archiver);
     fm_key_file_get_bool(kf, "config", "thumbnail_local", &cfg->thumbnail_local);
     fm_key_file_get_int(kf, "config", "thumbnail_max", &cfg->thumbnail_max);
     fm_key_file_get_bool(kf, "config", "advanced_mode", &cfg->advanced_mode);
@@ -285,8 +294,7 @@ void fm_config_load_from_key_file(FmConfig* cfg, GKeyFile* kf)
     fm_key_file_get_bool(kf, "config", "defer_content_test", &cfg->defer_content_test);
     fm_key_file_get_bool(kf, "config", "quick_exec", &cfg->quick_exec);
     fm_key_file_get_bool(kf, "config", "smart_desktop_autodrop", &cfg->smart_desktop_autodrop);
-    g_free(cfg->format_cmd);
-    cfg->format_cmd = g_key_file_get_string(kf, "config", "format_cmd", NULL);
+    fm_key_file_get_string(kf, "config", "format_cmd", &cfg->format_cmd);
     /* append blacklist */
     strv = g_key_file_get_string_list(kf, "config", "modules_blacklist", NULL, NULL);
     fm_strcatv(&cfg->modules_blacklist, strv);
@@ -305,10 +313,8 @@ void fm_config_load_from_key_file(FmConfig* cfg, GKeyFile* kf)
     fm_key_file_get_int(kf, "ui", "thumbnail_size", &cfg->thumbnail_size);
     fm_key_file_get_bool(kf, "ui", "show_thumbnail", &cfg->show_thumbnail);
     fm_key_file_get_bool(kf, "ui", "shadow_hidden", &cfg->shadow_hidden);
-    g_free(cfg->list_view_size_units);
-    cfg->list_view_size_units = g_key_file_get_string(kf, "ui", "list_view_size_units", NULL);
-    g_free(cfg->saved_search);
-    cfg->saved_search = g_key_file_get_string(kf, "ui", "saved_search", NULL);
+    fm_key_file_get_string(kf, "ui", "list_view_size_units", &cfg->list_view_size_units);
+    fm_key_file_get_string(kf, "ui", "saved_search",  &cfg->saved_search);
 
     fm_key_file_get_bool(kf, "places", "places_home", &cfg->places_home);
     fm_key_file_get_bool(kf, "places", "places_desktop", &cfg->places_desktop);
-- 
2.33.1

