Skip to content

Commit 1274a15

Browse files
committed
config: use git_config_parse_key() in git_config_parse_parameter()
The parsing of one-shot assignments of configuration variables that come from the command line historically was quite loose and allowed anything to pass. It also downcased everything in the variable name, even a three-level <section>.<subsection>.<variable> name in which the <subsection> part must be treated in a case sensitive manner. Existing git_config_parse_key() helper is used to parse the variable name that comes from the command line, i.e. "git config VAR VAL", and handles these details correctly. Replace the strbuf_tolower() call in git_config_parse_parameter() with a call to it to correct both issues. git_config_parse_key() does a bit more things that are not necessary for the purpose of this codepath (e.g. it allocates a separate buffer to return the canonicalized variable name because it takes a "const char *" input), but we are not in a performance-critical codepath here. Signed-off-by: Junio C Hamano <[email protected]>
1 parent ee98df3 commit 1274a15

File tree

2 files changed

+71
-5
lines changed

2 files changed

+71
-5
lines changed

config.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ int git_config_parse_parameter(const char *text,
295295
config_fn_t fn, void *data)
296296
{
297297
const char *value;
298+
char *canonical_name;
298299
struct strbuf **pair;
300+
int ret;
299301

300302
pair = strbuf_split_str(text, '=', 2);
301303
if (!pair[0])
@@ -313,13 +315,15 @@ int git_config_parse_parameter(const char *text,
313315
strbuf_list_free(pair);
314316
return error("bogus config parameter: %s", text);
315317
}
316-
strbuf_tolower(pair[0]);
317-
if (fn(pair[0]->buf, value, data) < 0) {
318-
strbuf_list_free(pair);
319-
return -1;
318+
319+
if (git_config_parse_key(pair[0]->buf, &canonical_name, NULL)) {
320+
ret = -1;
321+
} else {
322+
ret = (fn(canonical_name, value, data) < 0) ? -1 : 0;
323+
free(canonical_name);
320324
}
321325
strbuf_list_free(pair);
322-
return 0;
326+
return ret;
323327
}
324328

325329
int git_config_from_parameters(config_fn_t fn, void *data)

t/t1300-repo-config.sh

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,68 @@ test_expect_success 'multiple git -c appends config' '
10971097
test_cmp expect actual
10981098
'
10991099

1100+
test_expect_success 'last one wins: two level vars' '
1101+
1102+
# sec.var and sec.VAR are the same variable, as the first
1103+
# and the last level of a configuration variable name is
1104+
# case insensitive.
1105+
1106+
echo VAL >expect &&
1107+
1108+
git -c sec.var=val -c sec.VAR=VAL config --get sec.var >actual &&
1109+
test_cmp expect actual &&
1110+
git -c SEC.var=val -c sec.var=VAL config --get sec.var >actual &&
1111+
test_cmp expect actual &&
1112+
1113+
git -c sec.var=val -c sec.VAR=VAL config --get SEC.var >actual &&
1114+
test_cmp expect actual &&
1115+
git -c SEC.var=val -c sec.var=VAL config --get sec.VAR >actual &&
1116+
test_cmp expect actual
1117+
'
1118+
1119+
test_expect_success 'last one wins: three level vars' '
1120+
1121+
# v.a.r and v.A.r are not the same variable, as the middle
1122+
# level of a three-level configuration variable name is
1123+
# case sensitive.
1124+
1125+
echo val >expect &&
1126+
git -c v.a.r=val -c v.A.r=VAL config --get v.a.r >actual &&
1127+
test_cmp expect actual &&
1128+
git -c v.a.r=val -c v.A.r=VAL config --get V.a.R >actual &&
1129+
test_cmp expect actual &&
1130+
1131+
# v.a.r and V.a.R are the same variable, as the first
1132+
# and the last level of a configuration variable name is
1133+
# case insensitive.
1134+
1135+
echo VAL >expect &&
1136+
git -c v.a.r=val -c v.a.R=VAL config --get v.a.r >actual &&
1137+
test_cmp expect actual &&
1138+
git -c v.a.r=val -c V.a.r=VAL config --get v.a.r >actual &&
1139+
test_cmp expect actual &&
1140+
git -c v.a.r=val -c v.a.R=VAL config --get V.a.R >actual &&
1141+
test_cmp expect actual &&
1142+
git -c v.a.r=val -c V.a.r=VAL config --get V.a.R >actual &&
1143+
test_cmp expect actual
1144+
'
1145+
1146+
for VAR in a .a a. a.0b a."b c". a."b c".0d
1147+
do
1148+
test_expect_success "git -c $VAR=VAL rejects invalid '$VAR'" '
1149+
test_must_fail git -c "$VAR=VAL" config -l
1150+
'
1151+
done
1152+
1153+
for VAR in a.b a."b c".d
1154+
do
1155+
test_expect_success "git -c $VAR=VAL works with valid '$VAR'" '
1156+
echo VAL >expect &&
1157+
git -c "$VAR=VAL" config --get "$VAR" >actual &&
1158+
test_cmp expect actual
1159+
'
1160+
done
1161+
11001162
test_expect_success 'git -c is not confused by empty environment' '
11011163
GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
11021164
'

0 commit comments

Comments
 (0)