Skip to content

Commit

Permalink
Merge branch 'jk/config-use-size-t'
Browse files Browse the repository at this point in the history
The config API made mixed uses of int and size_t types to represent
length of various pieces of text it parsed, which has been updated
to use the correct type (i.e. size_t) throughout.

* jk/config-use-size-t:
  config: reject parsing of files over INT_MAX
  config: use size_t to store parsed variable baselen
  git_config_parse_key(): return baselen as size_t
  config: drop useless length variable in write_pair()
  parse_config_key(): return subsection len as size_t
  remote: drop auto-strlen behavior of make_branch() and make_rewrite()
  • Loading branch information
gitster committed Apr 28, 2020
2 parents 2abd648 + 348482d commit 342bc9e
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 50 deletions.
4 changes: 2 additions & 2 deletions archive-tar.c
Expand Up @@ -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++) {
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion builtin/help.c
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion builtin/reflog.c
Expand Up @@ -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;
Expand Down
42 changes: 29 additions & 13 deletions config.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

/*
Expand Down Expand Up @@ -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, '.');

/*
Expand Down Expand Up @@ -425,7 +427,7 @@ static int git_config_parse_key_1(const char *key, char **store_key, int *basele
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);
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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]) {
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions config.h
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

/**
Expand Down
2 changes: 1 addition & 1 deletion convert.c
Expand Up @@ -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;

/*
Expand Down
2 changes: 1 addition & 1 deletion fsck.c
Expand Up @@ -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 ||
Expand Down
2 changes: 1 addition & 1 deletion ll-merge.c
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion promisor-remote.c
Expand Up @@ -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"))
Expand Down
37 changes: 13 additions & 24 deletions remote.c
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion submodule-config.c
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions userdiff.c
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 342bc9e

Please sign in to comment.