prepare_repo_settings(): plug leak of config values

We call repo_config_get_string() for fetch.negotiationAlgorithm, which allocates a copy of the string, but we never free it. We could add a call to free(), but there's an even simpler solution: we don't need the string to persist beyond a few strcasecmp() calls, so we can instead use the "_tmp" variant which gives us a const pointer to the cached value. We need to switch the type of "strval" to "const char *" for this to work, which affects a similar call that checks core.untrackedCache. But it's in the same boat! It doesn't actually need the value to persist beyond a maybe_bool() check (though it does remember to correctly free the string afterwards). So we can simplify it at the same time. Note that this core.untrackedCache check arguably should be using repo_config_get_maybe_bool(), but there are some subtle behavior changes. E.g., it doesn't currently allow a value-less "true". Arguably it should, but let's avoid lumping further changes in what should be a simple leak cleanup. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Sep 8, 2022 at 01:02 UTC 66eede4a37c3e17ccadbd99fe0f07a4a133d495d
1 file changed +3 -4
repo-settings.c
+3 -4
@@ -15,7 +15,7 @@ void prepare_repo_settings(struct repository *r)
15 {
16 int experimental;
17 int value;
18 - char *strval;
18 + const char *strval;
19 int manyfiles;
20
21 if (!r->gitdir)
@@ -67,7 +67,7 @@ void prepare_repo_settings(struct repository *r)
67 if (!repo_config_get_int(r, "index.version", &value))
68 r->settings.index_version = value;
69
70 - if (!repo_config_get_string(r, "core.untrackedcache", &strval)) {
70 + if (!repo_config_get_string_tmp(r, "core.untrackedcache", &strval)) {
71 int v = git_parse_maybe_bool(strval);
72
73 /*
@@ -78,10 +78,9 @@ void prepare_repo_settings(struct repository *r)
78 if (v >= 0)
79 r->settings.core_untracked_cache = v ?
80 UNTRACKED_CACHE_WRITE : UNTRACKED_CACHE_REMOVE;
81 - free(strval);
81 }
82
84 - if (!repo_config_get_string(r, "fetch.negotiationalgorithm", &strval)) {
83 + if (!repo_config_get_string_tmp(r, "fetch.negotiationalgorithm", &strval)) {
84 int fetch_default = r->settings.fetch_negotiation_algorithm;
85 if (!strcasecmp(strval, "skipping"))
86 r->settings.fetch_negotiation_algorithm = FETCH_NEGOTIATION_SKIPPING;