diff options
-rw-r--r-- | archive-tar.c | 4 | ||||
-rw-r--r-- | builtin/help.c | 2 | ||||
-rw-r--r-- | builtin/reflog.c | 2 | ||||
-rw-r--r-- | config.c | 42 | ||||
-rw-r--r-- | config.h | 4 | ||||
-rw-r--r-- | convert.c | 2 | ||||
-rw-r--r-- | fsck.c | 2 | ||||
-rw-r--r-- | ll-merge.c | 2 | ||||
-rw-r--r-- | promisor-remote.c | 2 | ||||
-rw-r--r-- | remote.c | 37 | ||||
-rw-r--r-- | submodule-config.c | 3 | ||||
-rw-r--r-- | userdiff.c | 4 |
12 files changed, 56 insertions, 50 deletions
diff --git a/archive-tar.c b/archive-tar.c index 5a77701a15..5ceec3684b 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -364,7 +364,7 @@ static struct archiver **tar_filters; static int nr_tar_filters; static int alloc_tar_filters; -static struct archiver *find_tar_filter(const char *name, int len) +static struct archiver *find_tar_filter(const char *name, size_t len) { int i; for (i = 0; i < nr_tar_filters; i++) { @@ -380,7 +380,7 @@ static int tar_filter_config(const char *var, const char *value, void *data) struct archiver *ar; const char *name; const char *type; - int namelen; + size_t namelen; if (parse_config_key(var, "tar", &name, &namelen, &type) < 0 || !name) return 0; diff --git a/builtin/help.c b/builtin/help.c index e5590d7787..c024110531 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -242,7 +242,7 @@ static int add_man_viewer_cmd(const char *name, static int add_man_viewer_info(const char *var, const char *value) { const char *name, *subkey; - int namelen; + size_t namelen; if (parse_config_key(var, "man", &name, &namelen, &subkey) < 0 || !name) return 0; diff --git a/builtin/reflog.c b/builtin/reflog.c index 81dfd563c0..52ecf6d43c 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -459,7 +459,7 @@ static struct reflog_expire_cfg *find_cfg_ent(const char *pattern, size_t len) static int reflog_expire_config(const char *var, const char *value, void *cb) { const char *pattern, *key; - int pattern_len; + size_t pattern_len; timestamp_t expire; int slot; struct reflog_expire_cfg *ent; @@ -37,6 +37,7 @@ struct config_source { enum config_error_action default_error_action; int linenr; int eof; + size_t total_len; struct strbuf value; struct strbuf var; unsigned subsection_case_sensitive : 1; @@ -309,7 +310,7 @@ int git_config_include(const char *var, const char *value, void *data) { struct config_include_data *inc = data; const char *cond, *key; - int cond_len; + size_t cond_len; int ret; /* @@ -358,12 +359,13 @@ static inline int iskeychar(int c) * * store_key - pointer to char* which will hold a copy of the key with * lowercase section and variable name - * baselen - pointer to int which will hold the length of the + * baselen - pointer to size_t which will hold the length of the * section + subsection part, can be NULL */ -static int git_config_parse_key_1(const char *key, char **store_key, int *baselen_, int quiet) +static int git_config_parse_key_1(const char *key, char **store_key, size_t *baselen_, int quiet) { - int i, dot, baselen; + size_t i, baselen; + int dot; const char *last_dot = strrchr(key, '.'); /* @@ -425,7 +427,7 @@ out_free_ret_1: return -CONFIG_INVALID_KEY; } -int git_config_parse_key(const char *key, char **store_key, int *baselen) +int git_config_parse_key(const char *key, char **store_key, size_t *baselen) { return git_config_parse_key_1(key, store_key, baselen, 0); } @@ -523,6 +525,19 @@ static int get_next_char(void) c = '\r'; } } + + if (c != EOF && ++cf->total_len > INT_MAX) { + /* + * This is an absurdly long config file; refuse to parse + * further in order to protect downstream code from integer + * overflows. Note that we can't return an error specifically, + * but we can mark EOF and put trash in the return value, + * which will trigger a parse error. + */ + cf->eof = 1; + return 0; + } + if (c == '\n') cf->linenr++; if (c == EOF) { @@ -728,7 +743,7 @@ static int git_parse_source(config_fn_t fn, void *data, const struct config_options *opts) { int comment = 0; - int baselen = 0; + size_t baselen = 0; struct strbuf *var = &cf->var; int error_return = 0; char *error_msg = NULL; @@ -1539,6 +1554,7 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data, top->prev = cf; top->linenr = 1; top->eof = 0; + top->total_len = 0; strbuf_init(&top->value, 1024); strbuf_init(&top->var, 1024); cf = top; @@ -2383,7 +2399,7 @@ void git_die_config(const char *key, const char *err, ...) */ struct config_store_data { - int baselen; + size_t baselen; char *key; int do_not_match; regex_t *value_regex; @@ -2509,7 +2525,7 @@ static struct strbuf store_create_section(const char *key, const struct config_store_data *store) { const char *dot; - int i; + size_t i; struct strbuf sb = STRBUF_INIT; dot = memchr(key, '.', store->baselen); @@ -2522,7 +2538,9 @@ static struct strbuf store_create_section(const char *key, } strbuf_addstr(&sb, "\"]\n"); } else { - strbuf_addf(&sb, "[%.*s]\n", store->baselen, key); + strbuf_addch(&sb, '['); + strbuf_add(&sb, key, store->baselen); + strbuf_addstr(&sb, "]\n"); } return sb; @@ -2545,7 +2563,6 @@ static ssize_t write_pair(int fd, const char *key, const char *value, { int i; ssize_t ret; - int length = strlen(key + store->baselen + 1); const char *quote = ""; struct strbuf sb = STRBUF_INIT; @@ -2564,8 +2581,7 @@ static ssize_t write_pair(int fd, const char *key, const char *value, if (i && value[i - 1] == ' ') quote = "\""; - strbuf_addf(&sb, "\t%.*s = %s", - length, key + store->baselen + 1, quote); + strbuf_addf(&sb, "\t%s = %s", key + store->baselen + 1, quote); for (i = 0; value[i]; i++) switch (value[i]) { @@ -3238,7 +3254,7 @@ int config_error_nonbool(const char *var) int parse_config_key(const char *var, const char *section, - const char **subsection, int *subsection_len, + const char **subsection, size_t *subsection_len, const char **key) { const char *dot; @@ -254,7 +254,7 @@ int git_config_set_gently(const char *, const char *); */ void git_config_set(const char *, const char *); -int git_config_parse_key(const char *, char **, int *); +int git_config_parse_key(const char *, char **, size_t *); int git_config_key_is_valid(const char *key); int git_config_set_multivar_gently(const char *, const char *, const char *, int); void git_config_set_multivar(const char *, const char *, const char *, int); @@ -359,7 +359,7 @@ int git_config_include(const char *name, const char *value, void *data); */ int parse_config_key(const char *var, const char *section, - const char **subsection, int *subsection_len, + const char **subsection, size_t *subsection_len, const char **key); /** @@ -1018,7 +1018,7 @@ static int apply_filter(const char *path, const char *src, size_t len, static int read_convert_config(const char *var, const char *value, void *cb) { const char *key, *name; - int namelen; + size_t namelen; struct convert_driver *drv; /* @@ -1065,7 +1065,7 @@ static int fsck_gitmodules_fn(const char *var, const char *value, void *vdata) { struct fsck_gitmodules_data *data = vdata; const char *subsection, *key; - int subsection_len; + size_t subsection_len; char *name; if (parse_config_key(var, "submodule", &subsection, &subsection_len, &key) < 0 || diff --git a/ll-merge.c b/ll-merge.c index d65a8971db..1ec0b959e0 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -247,7 +247,7 @@ static int read_merge_config(const char *var, const char *value, void *cb) { struct ll_merge_driver *fn; const char *key, *name; - int namelen; + size_t namelen; if (!strcmp(var, "merge.default")) return git_config_string(&default_ll_merge, var, value); diff --git a/promisor-remote.c b/promisor-remote.c index 9f338c945f..ff8721fd56 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -101,7 +101,7 @@ static void promisor_remote_move_to_tail(struct promisor_remote *r, static int promisor_remote_config(const char *var, const char *value, void *data) { const char *name; - int namelen; + size_t namelen; const char *subkey; if (!strcmp(var, "core.partialclonefilter")) @@ -174,54 +174,43 @@ static void add_merge(struct branch *branch, const char *name) branch->merge_name[branch->merge_nr++] = name; } -static struct branch *make_branch(const char *name, int len) +static struct branch *make_branch(const char *name, size_t len) { struct branch *ret; int i; for (i = 0; i < branches_nr; i++) { - if (len ? (!strncmp(name, branches[i]->name, len) && - !branches[i]->name[len]) : - !strcmp(name, branches[i]->name)) + if (!strncmp(name, branches[i]->name, len) && + !branches[i]->name[len]) return branches[i]; } ALLOC_GROW(branches, branches_nr + 1, branches_alloc); ret = xcalloc(1, sizeof(struct branch)); branches[branches_nr++] = ret; - if (len) - ret->name = xstrndup(name, len); - else - ret->name = xstrdup(name); + ret->name = xstrndup(name, len); ret->refname = xstrfmt("refs/heads/%s", ret->name); return ret; } -static struct rewrite *make_rewrite(struct rewrites *r, const char *base, int len) +static struct rewrite *make_rewrite(struct rewrites *r, + const char *base, size_t len) { struct rewrite *ret; int i; for (i = 0; i < r->rewrite_nr; i++) { - if (len - ? (len == r->rewrite[i]->baselen && - !strncmp(base, r->rewrite[i]->base, len)) - : !strcmp(base, r->rewrite[i]->base)) + if (len == r->rewrite[i]->baselen && + !strncmp(base, r->rewrite[i]->base, len)) return r->rewrite[i]; } ALLOC_GROW(r->rewrite, r->rewrite_nr + 1, r->rewrite_alloc); ret = xcalloc(1, sizeof(struct rewrite)); r->rewrite[r->rewrite_nr++] = ret; - if (len) { - ret->base = xstrndup(base, len); - ret->baselen = len; - } - else { - ret->base = xstrdup(base); - ret->baselen = strlen(base); - } + ret->base = xstrndup(base, len); + ret->baselen = len; return ret; } @@ -316,7 +305,7 @@ static void read_branches_file(struct remote *remote) static int handle_config(const char *key, const char *value, void *cb) { const char *name; - int namelen; + size_t namelen; const char *subkey; struct remote *remote; struct branch *branch; @@ -470,7 +459,7 @@ static void read_config(void) const char *head_ref = resolve_ref_unsafe("HEAD", 0, NULL, &flag); if (head_ref && (flag & REF_ISSYMREF) && skip_prefix(head_ref, "refs/heads/", &head_ref)) { - current_branch = make_branch(head_ref, 0); + current_branch = make_branch(head_ref, strlen(head_ref)); } } git_config(handle_config, NULL); @@ -1584,7 +1573,7 @@ struct branch *branch_get(const char *name) if (!name || !*name || !strcmp(name, "HEAD")) ret = current_branch; else - ret = make_branch(name, 0); + ret = make_branch(name, strlen(name)); set_merge(ret); return ret; } diff --git a/submodule-config.c b/submodule-config.c index 4d1c92d582..e175dfbc38 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -225,7 +225,8 @@ static int name_and_item_from_var(const char *var, struct strbuf *name, struct strbuf *item) { const char *subsection, *key; - int subsection_len, parse; + size_t subsection_len; + int parse; parse = parse_config_key(var, "submodule", &subsection, &subsection_len, &key); if (parse < 0 || !subsection) diff --git a/userdiff.c b/userdiff.c index efbe05e5a5..30ab42df8e 100644 --- a/userdiff.c +++ b/userdiff.c @@ -222,7 +222,7 @@ static struct userdiff_driver driver_false = { { NULL, 0 } }; -static struct userdiff_driver *userdiff_find_by_namelen(const char *k, int len) +static struct userdiff_driver *userdiff_find_by_namelen(const char *k, size_t len) { int i; for (i = 0; i < ndrivers; i++) { @@ -266,7 +266,7 @@ int userdiff_config(const char *k, const char *v) { struct userdiff_driver *drv; const char *name, *type; - int namelen; + size_t namelen; if (parse_config_key(k, "diff", &name, &namelen, &type) || !name) return 0; |