From 47854c5fdbdebaf707de438f0fa86c4cb99d2268 Mon Sep 17 00:00:00 2001 Message-Id: <47854c5fdbdebaf707de438f0fa86c4cb99d2268.1715894362.git.mdw@distorted.org.uk> From: Mark Wooding Date: Wed, 25 Nov 2009 10:57:30 +0000 Subject: [PATCH] Some configuration-related memory hygeine. Organization: Straylight/Edgeware From: Richard Kettlewell Use of libgc means we don't have to worry about memory leakage as such in most of the code. But in some cases libgc isn't appropriate and GTK+ doesn't get on well with it (or at least used not to). --- clients/disorder.c | 11 ++++++++--- disobedience/login.c | 6 ++++-- lib/asprintf.c | 6 +++++- lib/configuration.c | 13 ++++++++----- lib/configuration.h | 6 ++++-- lib/vector.c | 13 +++++++++++++ lib/vector.h | 3 +++ 7 files changed, 45 insertions(+), 13 deletions(-) diff --git a/clients/disorder.c b/clients/disorder.c index 1d55b8d..298494a 100644 --- a/clients/disorder.c +++ b/clients/disorder.c @@ -864,11 +864,14 @@ int main(int argc, char **argv) { } if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration"); if(user) { - config->username = user; + xfree(config->username); + config->username = xstrdup(user); config->password = 0; } - if(password) - config->password = password; + if(password) { + xfree(config->password); + config->password = xstrdup(password); + } if(local) config->connect.af = -1; if(wfr) @@ -899,10 +902,12 @@ int main(int argc, char **argv) { vector_append(&args, nullcheck(mb2utf8(argv[n + j]))); vector_terminate(&args); commands[i].fn(args.vec + 1); + xfree(args.vec); n += j; } if(client && disorder_close(client)) exit(EXIT_FAILURE); if(fclose(stdout) < 0) disorder_fatal(errno, "error closing stdout"); + config_free(config); return status; } diff --git a/disobedience/login.c b/disobedience/login.c index 36850c1..90eaa0d 100644 --- a/disobedience/login.c +++ b/disobedience/login.c @@ -120,11 +120,13 @@ static void set_service(struct config *c, const char *s) { } static void set_username(struct config *c, const char *s) { - c->username = s; + xfree(c->username); + c->username = xstrdup(s); } static void set_password(struct config *c, const char *s) { - c->password = s; + xfree(c->password); + c->password = xstrdup(s); } /** @brief Table used to generate the form */ diff --git a/lib/asprintf.c b/lib/asprintf.c index da37319..ddfc12e 100644 --- a/lib/asprintf.c +++ b/lib/asprintf.c @@ -38,11 +38,15 @@ int byte_vasprintf(char **ptrp, const char *fmt, va_list ap) { + struct sink *s; struct dynstr d; int n; dynstr_init(&d); - if((n = byte_vsinkprintf(sink_dynstr(&d), fmt, ap)) >= 0) { + s = sink_dynstr(&d); + n = byte_vsinkprintf(s, fmt, ap); + xfree(s); + if(n >= 0) { dynstr_terminate(&d); *ptrp = d.vec; } diff --git a/lib/configuration.c b/lib/configuration.c index e2af880..c059bf7 100644 --- a/lib/configuration.c +++ b/lib/configuration.c @@ -240,6 +240,7 @@ static int set_string(const struct config_state *cs, cs->path, cs->line, whoami->name); return -1; } + xfree(VALUE(cs->config, char *)); VALUE(cs->config, char *) = xstrdup(vec[0]); return 0; } @@ -520,8 +521,7 @@ static int set_rights(const struct config_state *cs, cs->path, cs->line, vec[0]); return -1; } - *ADDRESS(cs->config, char *) = vec[0]; - return 0; + return set_string(cs, whoami, nvec, vec); } static int set_netaddress(const struct config_state *cs, @@ -644,7 +644,7 @@ static const struct conftype type_namepart = { set_namepart, free_namepartlist }, type_transform = { set_transform, free_transformlist }, type_netaddress = { set_netaddress, free_netaddress }, - type_rights = { set_rights, free_none }; + type_rights = { set_rights, free_string }; /* specific validation routine */ @@ -1047,6 +1047,7 @@ static int validate_destaddr(const struct config_state attribute((unused)) *cs, disorder_error(0, "%s:%d: destination address required", cs->path, cs->line); return -1; } + xfree(na->address); return 0; } @@ -1174,7 +1175,9 @@ static int config_set_args(const struct config_state *cs, vector_append(v, s); va_end(ap); vector_terminate(v); - return config_set(cs, v->nvec, v->vec); + int rc = config_set(cs, v->nvec, v->vec); + xfree(v->vec); + return rc; } /** @brief Error callback used by config_include() @@ -1415,7 +1418,7 @@ static void set_configfile(void) { * * @p c is indeterminate after this function is called. */ -static void config_free(struct config *c) { +void config_free(struct config *c) { int n; if(c) { diff --git a/lib/configuration.h b/lib/configuration.h index 9170a2f..f1794aa 100644 --- a/lib/configuration.h +++ b/lib/configuration.h @@ -195,10 +195,10 @@ struct config { const char *home; /** @brief Login username */ - const char *username; + char *username; /** @brief Login password */ - const char *password; + char *password; /** @brief Address to connect to */ struct netaddress connect; @@ -320,6 +320,8 @@ char *config_usersysconf(const struct passwd *pw ); char *config_private(void); /* get the private config file */ +void config_free(struct config *c); + extern char *configfile; extern int config_per_user; diff --git a/lib/vector.c b/lib/vector.c index 4d798f1..65a84e0 100644 --- a/lib/vector.c +++ b/lib/vector.c @@ -38,6 +38,19 @@ void dynstr_append_bytes(struct dynstr *v, const char *ptr, size_t n) { } } +/** @brief Free a string list */ +void free_strings(int nvec, char **vec) { + for(int n = 0; n < nvec; ++n) + xfree(vec[n]); + xfree(vec); +} + +/** @brief Free and re-initialize a vector */ +void vector_clear(struct vector *v) { + free_strings(v->nvec, v->vec); + vector_init(v); +} + /* Local Variables: c-basic-offset:2 diff --git a/lib/vector.h b/lib/vector.h index 31dfeda..5bd9b97 100644 --- a/lib/vector.h +++ b/lib/vector.h @@ -94,6 +94,9 @@ static inline void dynstr_append_string(struct dynstr *v, const char *ptr) { dynstr_append_bytes(v, ptr, strlen(ptr)); } +void free_strings(int nvec, char **vec); +void vector_clear(struct vector *v); + #endif /* VECTOR_H */ /* -- [mdw]