diff options
Diffstat (limited to 'config.c')
| -rw-r--r-- | config.c | 82 |
1 files changed, 68 insertions, 14 deletions
@@ -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; } |
