aboutsummaryrefslogtreecommitdiffstats
path: root/config.c
diff options
context:
space:
mode:
Diffstat (limited to 'config.c')
-rw-r--r--config.c82
1 files changed, 68 insertions, 14 deletions
diff --git a/config.c b/config.c
index a5e11aad7f..27f38283ad 100644
--- a/config.c
+++ b/config.c
@@ -81,6 +81,17 @@ static enum config_scope current_parsing_scope;
static int pack_compression_seen;
static int zlib_compression_seen;
+/*
+ * Config that comes from trusted scopes, namely:
+ * - CONFIG_SCOPE_SYSTEM (e.g. /etc/gitconfig)
+ * - CONFIG_SCOPE_GLOBAL (e.g. $HOME/.gitconfig, $XDG_CONFIG_HOME/git)
+ * - CONFIG_SCOPE_COMMAND (e.g. "-c" option, environment variables)
+ *
+ * This is declared here for code cleanliness, but unlike the other
+ * static variables, this does not hold config parser state.
+ */
+static struct config_set protected_config;
+
static int config_file_fgetc(struct config_source *conf)
{
return getc_unlocked(conf->u.file);
@@ -351,7 +362,8 @@ static void populate_remote_urls(struct config_include_data *inc)
current_parsing_scope = store_scope;
}
-static int forbid_remote_url(const char *var, const char *value, void *data)
+static int forbid_remote_url(const char *var, const char *value UNUSED,
+ void *data UNUSED)
{
const char *remote_name;
size_t remote_name_len;
@@ -1148,21 +1160,26 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
if (value && *value) {
char *end;
intmax_t val;
- uintmax_t uval;
- uintmax_t factor;
+ intmax_t factor;
+
+ if (max < 0)
+ BUG("max must be a positive integer");
errno = 0;
val = strtoimax(value, &end, 0);
if (errno == ERANGE)
return 0;
+ if (end == value) {
+ errno = EINVAL;
+ return 0;
+ }
factor = get_unit_factor(end);
if (!factor) {
errno = EINVAL;
return 0;
}
- uval = val < 0 ? -val : val;
- if (unsigned_mult_overflows(factor, uval) ||
- factor * uval > max) {
+ if ((val < 0 && -max / factor > val) ||
+ (val > 0 && max / factor < val)) {
errno = ERANGE;
return 0;
}
@@ -1181,10 +1198,19 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
uintmax_t val;
uintmax_t factor;
+ /* negative values would be accepted by strtoumax */
+ if (strchr(value, '-')) {
+ errno = EINVAL;
+ return 0;
+ }
errno = 0;
val = strtoumax(value, &end, 0);
if (errno == ERANGE)
return 0;
+ if (end == value) {
+ errno = EINVAL;
+ return 0;
+ }
factor = get_unit_factor(end);
if (!factor) {
errno = EINVAL;
@@ -1203,7 +1229,7 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
return 0;
}
-static int git_parse_int(const char *value, int *ret)
+int git_parse_int(const char *value, int *ret)
{
intmax_t tmp;
if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
@@ -1342,7 +1368,7 @@ static const struct fsync_component_name {
static enum fsync_component parse_fsync_components(const char *var, const char *string)
{
- enum fsync_component current = FSYNC_COMPONENTS_DEFAULT;
+ enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT;
enum fsync_component positive = 0, negative = 0;
while (string) {
@@ -1688,6 +1714,8 @@ static int git_default_core_config(const char *var, const char *value, void *cb)
fsync_method = FSYNC_METHOD_FSYNC;
else if (!strcmp(value, "writeout-only"))
fsync_method = FSYNC_METHOD_WRITEOUT_ONLY;
+ else if (!strcmp(value, "batch"))
+ fsync_method = FSYNC_METHOD_BATCH;
else
warning(_("ignoring unknown core.fsyncMethod value '%s'"), value);
@@ -1781,6 +1809,9 @@ static int git_default_branch_config(const char *var, const char *value)
} else if (value && !strcmp(value, "inherit")) {
git_branch_track = BRANCH_TRACK_INHERIT;
return 0;
+ } else if (value && !strcmp(value, "simple")) {
+ git_branch_track = BRANCH_TRACK_SIMPLE;
+ return 0;
}
git_branch_track = git_config_bool(var, value);
return 0;
@@ -1963,6 +1994,8 @@ int git_config_from_file_with_options(config_fn_t fn, const char *filename,
int ret = -1;
FILE *f;
+ if (!filename)
+ BUG("filename cannot be NULL");
f = fopen_or_warn(filename, "r");
if (f) {
ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename,
@@ -2319,10 +2352,10 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
return 0;
}
-static int config_set_element_cmp(const void *unused_cmp_data,
+static int config_set_element_cmp(const void *cmp_data UNUSED,
const struct hashmap_entry *eptr,
const struct hashmap_entry *entry_or_key,
- const void *unused_keydata)
+ const void *keydata UNUSED)
{
const struct config_set_element *e1, *e2;
@@ -2614,6 +2647,27 @@ int repo_config_get_pathname(struct repository *repo,
return ret;
}
+/* Read values into protected_config. */
+static void read_protected_config(void)
+{
+ struct config_options opts = {
+ .respect_includes = 1,
+ .ignore_repo = 1,
+ .ignore_worktree = 1,
+ .system_gently = 1,
+ };
+ git_configset_init(&protected_config);
+ config_with_options(config_set_callback, &protected_config,
+ NULL, &opts);
+}
+
+void git_protected_config(config_fn_t fn, void *data)
+{
+ if (!protected_config.hash_initialized)
+ read_protected_config();
+ configset_iter(&protected_config, fn, data);
+}
+
/* Functions used historically to read configuration from 'the_repository' */
void git_config(config_fn_t fn, void *data)
{
@@ -3190,7 +3244,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
goto out_free;
}
/* if nothing to unset, error out */
- if (value == NULL) {
+ if (!value) {
ret = CONFIG_NOTHING_SET;
goto out_free;
}
@@ -3206,7 +3260,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
int i, new_line = 0;
struct config_options opts;
- if (value_pattern == NULL)
+ if (!value_pattern)
store.value_pattern = NULL;
else if (value_pattern == CONFIG_REGEX_NONE)
store.value_pattern = CONFIG_REGEX_NONE;
@@ -3346,7 +3400,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
}
/* write the pair (value == NULL means unset) */
- if (value != NULL) {
+ if (value) {
if (!store.section_seen) {
if (write_section(fd, key, &store) < 0)
goto write_err_out;
@@ -3567,7 +3621,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
offset = section_name_match(&buf[i], old_name);
if (offset > 0) {
ret++;
- if (new_name == NULL) {
+ if (!new_name) {
remove = 1;
continue;
}