Skip to content

Commit 0534b78

Browse files
committed
Merge branch 'jc/optional-path'
"git config get --path" segfaulted on an ":(optional)path" that does not exist, which has been corrected. * jc/optional-path: config: really treat missing optional path as not configured config: really pretend missing :(optional) value is not there config: mark otherwise unused function as file-scope static
2 parents 5eadcbf + 0bd1685 commit 0534b78

11 files changed

Lines changed: 102 additions & 23 deletions

File tree

builtin/blame.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,8 @@ static int git_blame_config(const char *var, const char *value,
739739
ret = git_config_pathname(&str, var, value);
740740
if (ret)
741741
return ret;
742-
string_list_insert(&ignore_revs_file_list, str);
742+
if (str)
743+
string_list_insert(&ignore_revs_file_list, str);
743744
free(str);
744745
return 0;
745746
}

builtin/config.c

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,12 @@ struct strbuf_list {
261261
int alloc;
262262
};
263263

264+
/*
265+
* Format the configuration key-value pair (`key_`, `value_`) and
266+
* append it into strbuf `buf`. Returns a negative value on failure,
267+
* 0 on success, 1 on a missing optional value (i.e., telling the
268+
* caller to pretend that <key_,value_> did not exist).
269+
*/
264270
static int format_config(const struct config_display_options *opts,
265271
struct strbuf *buf, const char *key_,
266272
const char *value_, const struct key_value_info *kvi)
@@ -299,7 +305,10 @@ static int format_config(const struct config_display_options *opts,
299305
char *v;
300306
if (git_config_pathname(&v, key_, value_) < 0)
301307
return -1;
302-
strbuf_addstr(buf, v);
308+
if (v)
309+
strbuf_addstr(buf, v);
310+
else
311+
return 1; /* :(optional)no-such-file */
303312
free((char *)v);
304313
} else if (opts->type == TYPE_EXPIRY_DATE) {
305314
timestamp_t t;
@@ -344,6 +353,7 @@ static int collect_config(const char *key_, const char *value_,
344353
struct collect_config_data *data = cb;
345354
struct strbuf_list *values = data->values;
346355
const struct key_value_info *kvi = ctx->kvi;
356+
int status;
347357

348358
if (!(data->get_value_flags & GET_VALUE_KEY_REGEXP) &&
349359
strcmp(key_, data->key))
@@ -361,8 +371,15 @@ static int collect_config(const char *key_, const char *value_,
361371
ALLOC_GROW(values->items, values->nr + 1, values->alloc);
362372
strbuf_init(&values->items[values->nr], 0);
363373

364-
return format_config(data->display_opts, &values->items[values->nr++],
365-
key_, value_, kvi);
374+
status = format_config(data->display_opts, &values->items[values->nr++],
375+
key_, value_, kvi);
376+
if (status < 0)
377+
return status;
378+
if (status) {
379+
strbuf_release(&values->items[--values->nr]);
380+
status = 0;
381+
}
382+
return status;
366383
}
367384

368385
static int get_value(const struct config_location_options *opts,
@@ -438,15 +455,23 @@ static int get_value(const struct config_location_options *opts,
438455
if (!values.nr && display_opts->default_value) {
439456
struct key_value_info kvi = KVI_INIT;
440457
struct strbuf *item;
458+
int status;
441459

442460
kvi_from_param(&kvi);
443461
ALLOC_GROW(values.items, values.nr + 1, values.alloc);
444462
item = &values.items[values.nr++];
445463
strbuf_init(item, 0);
446-
if (format_config(display_opts, item, key_,
447-
display_opts->default_value, &kvi) < 0)
464+
465+
status = format_config(display_opts, item, key_,
466+
display_opts->default_value, &kvi);
467+
if (status < 0)
448468
die(_("failed to format default config value: %s"),
449469
display_opts->default_value);
470+
if (status) {
471+
/* default was a missing optional value */
472+
values.nr--;
473+
strbuf_release(item);
474+
}
450475
}
451476

452477
ret = !values.nr;
@@ -714,11 +739,13 @@ static int get_urlmatch(const struct config_location_options *opts,
714739
for_each_string_list_item(item, &values) {
715740
struct urlmatch_current_candidate_value *matched = item->util;
716741
struct strbuf buf = STRBUF_INIT;
742+
int status;
717743

718-
format_config(&display_opts, &buf, item->string,
719-
matched->value_is_null ? NULL : matched->value.buf,
720-
&matched->kvi);
721-
fwrite(buf.buf, 1, buf.len, stdout);
744+
status = format_config(&display_opts, &buf, item->string,
745+
matched->value_is_null ? NULL : matched->value.buf,
746+
&matched->kvi);
747+
if (!status)
748+
fwrite(buf.buf, 1, buf.len, stdout);
722749
strbuf_release(&buf);
723750

724751
strbuf_release(&matched->value);

builtin/receive-pack.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,9 @@ static int receive_pack_config(const char *var, const char *value,
177177

178178
if (git_config_pathname(&path, var, value))
179179
return -1;
180-
strbuf_addf(&fsck_msg_types, "%cskiplist=%s",
181-
fsck_msg_types.len ? ',' : '=', path);
180+
if (path)
181+
strbuf_addf(&fsck_msg_types, "%cskiplist=%s",
182+
fsck_msg_types.len ? ',' : '=', path);
182183
free(path);
183184
return 0;
184185
}

config.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1291,6 +1291,7 @@ int git_config_pathname(char **dest, const char *var, const char *value)
12911291

12921292
if (is_optional && is_missing_file(path)) {
12931293
free(path);
1294+
*dest = NULL;
12941295
return 0;
12951296
}
12961297

@@ -1953,7 +1954,7 @@ int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *d
19531954
return 1;
19541955
}
19551956

1956-
int git_configset_get_pathname(struct config_set *set, const char *key, char **dest)
1957+
static int git_configset_get_pathname(struct config_set *set, const char *key, char **dest)
19571958
{
19581959
const char *value;
19591960
if (!git_configset_get_value(set, key, &value, NULL))

config.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,6 @@ int git_configset_get_ulong(struct config_set *cs, const char *key, unsigned lon
564564
int git_configset_get_bool(struct config_set *cs, const char *key, int *dest);
565565
int git_configset_get_bool_or_int(struct config_set *cs, const char *key, int *is_bool, int *dest);
566566
int git_configset_get_maybe_bool(struct config_set *cs, const char *key, int *dest);
567-
int git_configset_get_pathname(struct config_set *cs, const char *key, char **dest);
568567

569568
/**
570569
* Run only the discover part of the repo_config_get_*() functions

fetch-pack.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,8 +1865,9 @@ int fetch_pack_fsck_config(const char *var, const char *value,
18651865

18661866
if (git_config_pathname(&path, var, value))
18671867
return -1;
1868-
strbuf_addf(msg_types, "%cskiplist=%s",
1869-
msg_types->len ? ',' : '=', path);
1868+
if (path)
1869+
strbuf_addf(msg_types, "%cskiplist=%s",
1870+
msg_types->len ? ',' : '=', path);
18701871
free(path);
18711872
return 0;
18721873
}

fsck.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,14 +1398,16 @@ int git_fsck_config(const char *var, const char *value,
13981398

13991399
if (strcmp(var, "fsck.skiplist") == 0) {
14001400
char *path;
1401-
struct strbuf sb = STRBUF_INIT;
14021401

14031402
if (git_config_pathname(&path, var, value))
14041403
return -1;
1405-
strbuf_addf(&sb, "skiplist=%s", path);
1406-
free(path);
1407-
fsck_set_msg_types(options, sb.buf);
1408-
strbuf_release(&sb);
1404+
if (path) {
1405+
struct strbuf sb = STRBUF_INIT;
1406+
strbuf_addf(&sb, "skiplist=%s", path);
1407+
free(path);
1408+
fsck_set_msg_types(options, sb.buf);
1409+
strbuf_release(&sb);
1410+
}
14091411
return 0;
14101412
}
14111413

gpg-interface.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,16 @@ static int git_gpg_config(const char *var, const char *value,
794794
fmtname = "ssh";
795795

796796
if (fmtname) {
797+
char *program;
798+
int status;
799+
797800
fmt = get_format_by_name(fmtname);
798-
return git_config_pathname((char **) &fmt->program, var, value);
801+
status = git_config_pathname(&program, var, value);
802+
if (status)
803+
return status;
804+
if (program)
805+
fmt->program = program;
806+
return status;
799807
}
800808

801809
return 0;

setup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1248,7 +1248,7 @@ static int safe_directory_cb(const char *key, const char *value,
12481248
} else {
12491249
char *allowed = NULL;
12501250

1251-
if (!git_config_pathname(&allowed, key, value)) {
1251+
if (!git_config_pathname(&allowed, key, value) && allowed) {
12521252
char *normalized = NULL;
12531253

12541254
/*

t/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ integration_tests = [
185185
't1308-config-set.sh',
186186
't1309-early-config.sh',
187187
't1310-config-default.sh',
188+
't1311-config-optional.sh',
188189
't1350-config-hooks-path.sh',
189190
't1400-update-ref.sh',
190191
't1401-symbolic-ref.sh',

0 commit comments

Comments
 (0)