summaryrefslogtreecommitdiff
path: root/config.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-05-18 22:44:23 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-05-27 17:45:40 (GMT)
commit9acc5911119ec0209877fbaa0a1e68aa714c191e (patch)
tree9a5bb0455b12bfd3e6fb3fdf4a6c0aca1af0992c /config.c
parent0d44a2dacc84fb7dcb5d684800e976f3b3c76d00 (diff)
downloadgit-9acc5911119ec0209877fbaa0a1e68aa714c191e.zip
git-9acc5911119ec0209877fbaa0a1e68aa714c191e.tar.gz
git-9acc5911119ec0209877fbaa0a1e68aa714c191e.tar.bz2
config: add a notion of "scope"
A config callback passed to git_config() doesn't know very much about the context in which it sees a variable. It can ask whether the variable comes from a file, and get the file name. But without analyzing the filename (which is hard to do accurately), it cannot tell whether it is in system-level config, user-level config, or repo-specific config. Generally this doesn't matter; the point of not passing this to the callback is that it should treat the config the same no matter where it comes from. But some programs, like upload-pack, are a special case: we should be able to run them in an untrusted repository, which means we cannot use any "dangerous" config from the repository config file (but it is OK to use it from system or user config). This patch teaches the config code to record the "scope" of each variable, and make it available inside config callbacks, similar to how we give access to the filename. The scope is the starting source for a particular parsing operation, and remains the same even if we include other files (so a .git/config which includes another file will remain CONFIG_SCOPE_REPO, as it would be similarly untrusted). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'config.c')
-rw-r--r--config.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/config.c b/config.c
index d555dee..8762916 100644
--- a/config.c
+++ b/config.c
@@ -57,6 +57,15 @@ struct config_source {
static struct config_source *cf;
static struct key_value_info *current_config_kvi;
+/*
+ * Similar to the variables above, this gives access to the "scope" of the
+ * current value (repo, global, etc). For cached values, it can be found via
+ * the current_config_kvi as above. During parsing, the current value can be
+ * found in this variable. It's not part of "cf" because it transcends a single
+ * file (i.e., a file included from .git/config is still in "repo" scope).
+ */
+static enum config_scope current_parsing_scope;
+
static int zlib_compression_seen;
/*
@@ -1229,22 +1238,27 @@ static int do_git_config_sequence(config_fn_t fn, void *data)
char *user_config = expand_user_path("~/.gitconfig");
char *repo_config = git_pathdup("config");
+ current_parsing_scope = CONFIG_SCOPE_SYSTEM;
if (git_config_system() && !access_or_die(git_etc_gitconfig(), R_OK, 0))
ret += git_config_from_file(fn, git_etc_gitconfig(),
data);
+ current_parsing_scope = CONFIG_SCOPE_GLOBAL;
if (xdg_config && !access_or_die(xdg_config, R_OK, ACCESS_EACCES_OK))
ret += git_config_from_file(fn, xdg_config, data);
if (user_config && !access_or_die(user_config, R_OK, ACCESS_EACCES_OK))
ret += git_config_from_file(fn, user_config, data);
+ current_parsing_scope = CONFIG_SCOPE_REPO;
if (repo_config && !access_or_die(repo_config, R_OK, 0))
ret += git_config_from_file(fn, repo_config, data);
+ current_parsing_scope = CONFIG_SCOPE_CMDLINE;
if (git_config_from_parameters(fn, data) < 0)
die(_("unable to parse command-line config"));
+ current_parsing_scope = CONFIG_SCOPE_UNKNOWN;
free(xdg_config);
free(user_config);
free(repo_config);
@@ -1383,6 +1397,7 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
kv_info->linenr = -1;
kv_info->origin_type = NULL;
}
+ kv_info->scope = current_parsing_scope;
si->util = kv_info;
return 0;
@@ -2482,3 +2497,11 @@ const char *current_config_name(void)
die("BUG: current_config_name called outside config callback");
return name ? name : "";
}
+
+enum config_scope current_config_scope(void)
+{
+ if (current_config_kvi)
+ return current_config_kvi->scope;
+ else
+ return current_parsing_scope;
+}