[Commits] [SCM] claws branch, master, updated. 3.15.0-80-g8c3760e

ticho at claws-mail.org ticho at claws-mail.org
Sun Jul 9 18:36:42 CEST 2017


The branch, master has been updated
       via  8c3760e3461510a1889195d2d027ebd4db6ca5bd (commit)
      from  99f705739502ca022401a95b776855eff551ce94 (commit)

Summary of changes:
 src/account.c       |    3 +--
 src/prefs_account.c |   30 ++++++++++++++++++++++++------
 src/prefs_account.h |    5 ++---
 3 files changed, 27 insertions(+), 11 deletions(-)


- Log -----------------------------------------------------------------
commit 8c3760e3461510a1889195d2d027ebd4db6ca5bd
Author: Andrej Kacian <ticho at claws-mail.org>
Date:   Sun Jul 9 18:27:20 2017 +0200

    Fix a long-standing memory leak in account prefs.
    
    All P_STRING type prefs with non-NULL default values
    were being leaked due to overly complicated account
    config loading, where we would first initialize
    a fresh PrefAccount, then load prefs from config, copying
    data between the static tmp_ac_prefs and our dynamically
    allocated PrefAccount several times.
    
    Instead of adding another round of data copying from/to
    tmp_ac_prefs for purpose of free()ing the P_STRING prefs,
    this commit changes prefs_account_read_config() into
    prefs_account_new_from_config(), a
    Existing accounts are now created with simple:
      ac_prefs = prefs_account_new_from_config(...);
    instead of previous:
      ac_prefs = prefs_account_new();
      prefs_account_read_from_config(ac_prefs, ...);
    
    The new function sets up contents of tmp_ac_prefs,
    and then its contents are only copied to the newly
    allocated PrefsAccount once.

diff --git a/src/account.c b/src/account.c
index 9625056..a152ef6 100644
--- a/src/account.c
+++ b/src/account.c
@@ -223,8 +223,7 @@ void account_read_config_all(void)
 	/* read config data from file */
 	cur_account = NULL;
 	for (cur = ac_label_list; cur != NULL; cur = cur->next) {
-		ac_prefs = prefs_account_new();
-		prefs_account_read_config(ac_prefs, (gchar *)cur->data);
+		ac_prefs = prefs_account_new_from_config((gchar *)cur->data);
 		account_list = g_list_append(account_list, ac_prefs);
 		if (ac_prefs->is_default)
 			cur_account = ac_prefs;
diff --git a/src/prefs_account.c b/src/prefs_account.c
index 589d63d..513ba6b 100644
--- a/src/prefs_account.c
+++ b/src/prefs_account.c
@@ -3574,20 +3574,31 @@ PrefsAccount *prefs_account_new(void)
 	return ac_prefs;
 }
 
-void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
+PrefsAccount *prefs_account_new_from_config(const gchar *label)
 {
 	const gchar *p = label;
 	gchar *rcpath;
 	gint id;
 	gchar **strv, **cur;
 	gsize len;
+	PrefsAccount *ac_prefs;
+
+	cm_return_val_if_fail(label != NULL, NULL);
 
-	cm_return_if_fail(ac_prefs != NULL);
-	cm_return_if_fail(label != NULL);
+	ac_prefs = g_new0(PrefsAccount, 1);
 
+	/* Load default values to tmp_ac_prefs first, ... */
 	memset(&tmp_ac_prefs, 0, sizeof(PrefsAccount));
-	tmp_ac_prefs.privacy_prefs = ac_prefs->privacy_prefs;
+	prefs_set_default(basic_param);
+	prefs_set_default(receive_param);
+	prefs_set_default(send_param);
+	prefs_set_default(compose_param);
+	prefs_set_default(templates_param);
+	prefs_set_default(privacy_param);
+	prefs_set_default(ssl_param);
+	prefs_set_default(advanced_param);
 
+	/* ... overriding them with values from stored config file. */
 	rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
 	prefs_read_config(basic_param, label, rcpath, NULL);
 	prefs_read_config(receive_param, label, rcpath, NULL);
@@ -3600,11 +3611,14 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
 	g_free(rcpath);
 
 	*ac_prefs = tmp_ac_prefs;
+
 	while (*p && !g_ascii_isdigit(*p)) p++;
 	id = atoi(p);
 	if (id < 0) g_warning("wrong account id: %d", id);
 	ac_prefs->account_id = id;
 
+	/* Now parse privacy_prefs. */
+	ac_prefs->privacy_prefs = g_hash_table_new(g_str_hash, g_str_equal);
 	if (privacy_prefs != NULL) {
 		strv = g_strsplit(privacy_prefs, ",", 0);
 		for (cur = strv; *cur != NULL; cur++) {
@@ -3627,6 +3641,8 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
 		privacy_prefs = NULL;
 	}
 
+	/* For older configurations, move stored passwords into the
+	 * password store. */
 	gboolean passwords_migrated = FALSE;
 
 	if (ac_prefs->passwd != NULL && strlen(ac_prefs->passwd) > 1) {
@@ -3652,14 +3668,16 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
 		passwords_migrated = TRUE;
 	}
 
-	/* Write out password store to file immediately after their move
-	 * from accountrc there. */
+	/* Write out password store to file immediately, to prevent
+	 * their loss. */
 	if (passwords_migrated)
 		passwd_store_write_config();
 
 	ac_prefs->receive_in_progress = FALSE;
 
 	prefs_custom_header_read_config(ac_prefs);
+
+	return ac_prefs;
 }
 
 static void create_privacy_prefs(gpointer key, gpointer _value, gpointer user_data)
diff --git a/src/prefs_account.h b/src/prefs_account.h
index 83f6efa..fd4dc1a 100644
--- a/src/prefs_account.h
+++ b/src/prefs_account.h
@@ -211,10 +211,9 @@ struct _PrefsAccount
 
 void prefs_account_init			(void);
 
-PrefsAccount *prefs_account_new		(void);
+PrefsAccount *prefs_account_new			(void);
+PrefsAccount *prefs_account_new_from_config	(const gchar	*label);
 
-void prefs_account_read_config		(PrefsAccount	*ac_prefs,
-					 const gchar	*label);
 void prefs_account_write_config_all	(GList		*account_list);
 
 void prefs_account_free			(PrefsAccount	*ac_prefs);

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list