aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2012-10-23 15:40:06 -0400
committerJeff King <peff@peff.net>2012-10-24 03:36:54 -0400
commit97ed50f93ba592b50278a8161282e862cb87b4c0 (patch)
tree6a68b9a01826980d5ca7486b83c4eb618c0fe090
parent35998c89381a56b28433852386986aafde92428d (diff)
downloadgit-97ed50f93ba592b50278a8161282e862cb87b4c0.tar.gz
git-97ed50f93ba592b50278a8161282e862cb87b4c0.tar.xz
git-config: fix regexp memory leaks on error conditions
The get_value function has a goto label for cleaning up on errors, but it only cleans up half of what the function might allocate. Let's also clean up the key and regexp variables there. Note that we need to take special care when compiling the regex fails to clean it up ourselves, since it is in a half-constructed state (we would want to free it, but not regfree it). Similarly, we fix git_config_parse_key to return NULL when it fails, not a pointer to some already-freed memory. Signed-off-by: Jeff King <peff@peff.net>
-rw-r--r--builtin/config.c23
-rw-r--r--config.c1
2 files changed, 14 insertions, 10 deletions
diff --git a/builtin/config.c b/builtin/config.c
index e660d4830..60d36e734 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -195,7 +195,8 @@ static int get_value(const char *key_, const char *regex_)
key_regexp = (regex_t*)xmalloc(sizeof(regex_t));
if (regcomp(key_regexp, key, REG_EXTENDED)) {
fprintf(stderr, "Invalid key pattern: %s\n", key_);
- free(key);
+ free(key_regexp);
+ key_regexp = NULL;
ret = CONFIG_INVALID_PATTERN;
goto free_strings;
}
@@ -215,6 +216,8 @@ static int get_value(const char *key_, const char *regex_)
regexp = (regex_t*)xmalloc(sizeof(regex_t));
if (regcomp(regexp, regex_, REG_EXTENDED)) {
fprintf(stderr, "Invalid pattern: %s\n", regex_);
+ free(regexp);
+ regexp = NULL;
ret = CONFIG_INVALID_PATTERN;
goto free_strings;
}
@@ -247,6 +250,15 @@ static int get_value(const char *key_, const char *regex_)
if (!do_all && !seen && system_wide)
git_config_from_file(fn, system_wide, data);
+ if (do_all)
+ ret = !seen;
+ else
+ ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
+
+free_strings:
+ free(repo_config);
+ free(global);
+ free(xdg);
free(key);
if (key_regexp) {
regfree(key_regexp);
@@ -257,15 +269,6 @@ static int get_value(const char *key_, const char *regex_)
free(regexp);
}
- if (do_all)
- ret = !seen;
- else
- ret = (seen == 1) ? 0 : seen > 1 ? 2 : 1;
-
-free_strings:
- free(repo_config);
- free(global);
- free(xdg);
return ret;
}
diff --git a/config.c b/config.c
index 08e47e2e4..2fbe634b1 100644
--- a/config.c
+++ b/config.c
@@ -1280,6 +1280,7 @@ int git_config_parse_key(const char *key, char **store_key, int *baselen_)
out_free_ret_1:
free(*store_key);
+ *store_key = NULL;
return -CONFIG_INVALID_KEY;
}