mirror of
https://github.com/git/git.git
synced 2024-05-12 11:46:07 +02:00
Merge branch 'ds/config-internal-whitespace-fix' into next
"git config" corrupted literal HT characters written in the configuration file as part of a value, which has been corrected. * ds/config-internal-whitespace-fix: config.txt: describe handling of whitespace further t1300: add more tests for whitespace and inline comments config: really keep value-internal whitespace verbatim config: minor addition of whitespace
This commit is contained in:
commit
f3393cabe5
|
@ -22,9 +22,10 @@ multivalued.
|
||||||
Syntax
|
Syntax
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
The syntax is fairly flexible and permissive; whitespaces are mostly
|
The syntax is fairly flexible and permissive. Whitespace characters,
|
||||||
ignored. The '#' and ';' characters begin comments to the end of line,
|
which in this context are the space character (SP) and the horizontal
|
||||||
blank lines are ignored.
|
tabulation (HT), are mostly ignored. The '#' and ';' characters begin
|
||||||
|
comments to the end of line. Blank lines are ignored.
|
||||||
|
|
||||||
The file consists of sections and variables. A section begins with
|
The file consists of sections and variables. A section begins with
|
||||||
the name of the section in square brackets and continues until the next
|
the name of the section in square brackets and continues until the next
|
||||||
|
@ -63,16 +64,17 @@ the variable is the boolean "true").
|
||||||
The variable names are case-insensitive, allow only alphanumeric characters
|
The variable names are case-insensitive, allow only alphanumeric characters
|
||||||
and `-`, and must start with an alphabetic character.
|
and `-`, and must start with an alphabetic character.
|
||||||
|
|
||||||
A line that defines a value can be continued to the next line by
|
Whitespace characters surrounding `name`, `=` and `value` are discarded.
|
||||||
ending it with a `\`; the backslash and the end-of-line are
|
Internal whitespace characters within 'value' are retained verbatim.
|
||||||
stripped. Leading whitespaces after 'name =', the remainder of the
|
Comments starting with either `#` or `;` and extending to the end of line
|
||||||
line after the first comment character '#' or ';', and trailing
|
are discarded. A line that defines a value can be continued to the next
|
||||||
whitespaces of the line are discarded unless they are enclosed in
|
line by ending it with a backslash (`\`); the backslash and the end-of-line
|
||||||
double quotes. Internal whitespaces within the value are retained
|
characters are discarded.
|
||||||
verbatim.
|
|
||||||
|
|
||||||
Inside double quotes, double quote `"` and backslash `\` characters
|
If `value` needs to contain leading or trailing whitespace characters,
|
||||||
must be escaped: use `\"` for `"` and `\\` for `\`.
|
it must be enclosed in double quotation marks (`"`). Inside double quotation
|
||||||
|
marks, double quote (`"`) and backslash (`\`) characters must be escaped:
|
||||||
|
use `\"` for `"` and `\\` for `\`.
|
||||||
|
|
||||||
The following escape sequences (beside `\"` and `\\`) are recognized:
|
The following escape sequences (beside `\"` and `\\`) are recognized:
|
||||||
`\n` for newline character (NL), `\t` for horizontal tabulation (HT, TAB)
|
`\n` for newline character (NL), `\t` for horizontal tabulation (HT, TAB)
|
||||||
|
|
15
config.c
15
config.c
|
@ -817,7 +817,8 @@ static int get_next_char(struct config_source *cs)
|
||||||
|
|
||||||
static char *parse_value(struct config_source *cs)
|
static char *parse_value(struct config_source *cs)
|
||||||
{
|
{
|
||||||
int quote = 0, comment = 0, space = 0;
|
int quote = 0, comment = 0;
|
||||||
|
size_t trim_len = 0;
|
||||||
|
|
||||||
strbuf_reset(&cs->value);
|
strbuf_reset(&cs->value);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -827,13 +828,17 @@ static char *parse_value(struct config_source *cs)
|
||||||
cs->linenr--;
|
cs->linenr--;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (trim_len)
|
||||||
|
strbuf_setlen(&cs->value, trim_len);
|
||||||
return cs->value.buf;
|
return cs->value.buf;
|
||||||
}
|
}
|
||||||
if (comment)
|
if (comment)
|
||||||
continue;
|
continue;
|
||||||
if (isspace(c) && !quote) {
|
if (isspace(c) && !quote) {
|
||||||
|
if (!trim_len)
|
||||||
|
trim_len = cs->value.len;
|
||||||
if (cs->value.len)
|
if (cs->value.len)
|
||||||
space++;
|
strbuf_addch(&cs->value, c);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!quote) {
|
if (!quote) {
|
||||||
|
@ -842,8 +847,8 @@ static char *parse_value(struct config_source *cs)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (; space; space--)
|
if (trim_len)
|
||||||
strbuf_addch(&cs->value, ' ');
|
trim_len = 0;
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
c = get_next_char(cs);
|
c = get_next_char(cs);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
@ -869,7 +874,7 @@ static char *parse_value(struct config_source *cs)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c == '"') {
|
if (c == '"') {
|
||||||
quote = 1-quote;
|
quote = 1 - quote;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
strbuf_addch(&cs->value, c);
|
strbuf_addch(&cs->value, c);
|
||||||
|
|
|
@ -11,6 +11,98 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
TEST_PASSES_SANITIZE_LEAK=true
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
|
test_expect_success 'setup whitespace config' '
|
||||||
|
sed -e "s/^|//" \
|
||||||
|
-e "s/[$]$//" \
|
||||||
|
-e "s/X/ /g" >.git/config <<-\EOF
|
||||||
|
[section]
|
||||||
|
| solid = rock
|
||||||
|
| sparse = big XX blue
|
||||||
|
| sparseAndTail = big XX blue $
|
||||||
|
| sparseAndTailQuoted = "big XX blue "
|
||||||
|
| sparseAndBiggerTail = big XX blue X X
|
||||||
|
| sparseAndBiggerTailQuoted = "big XX blue X X"
|
||||||
|
| sparseAndBiggerTailQuotedPlus = "big XX blue X X"X $
|
||||||
|
| headAndTail = Xbig blue $
|
||||||
|
| headAndTailQuoted = "Xbig blue "
|
||||||
|
| headAndTailQuotedPlus = "Xbig blue " $
|
||||||
|
| annotated = big blueX# to be discarded
|
||||||
|
| annotatedQuoted = "big blue"X# to be discarded
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'no internal whitespace' '
|
||||||
|
echo "rock" >expect &&
|
||||||
|
git config --get section.solid >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal whitespace' '
|
||||||
|
echo "big QQ blue" | q_to_tab >expect &&
|
||||||
|
git config --get section.sparse >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal and trailing whitespace' '
|
||||||
|
echo "big QQ blue" | q_to_tab >expect &&
|
||||||
|
git config --get section.sparseAndTail >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal and trailing whitespace, all quoted' '
|
||||||
|
echo "big QQ blue " | q_to_tab >expect &&
|
||||||
|
git config --get section.sparseAndTailQuoted >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal and more trailing whitespace' '
|
||||||
|
echo "big QQ blue" | q_to_tab >expect &&
|
||||||
|
git config --get section.sparseAndBiggerTail >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal and more trailing whitespace, all quoted' '
|
||||||
|
echo "big QQ blue Q Q" | q_to_tab >expect &&
|
||||||
|
git config --get section.sparseAndBiggerTailQuoted >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'internal and more trailing whitespace, not all quoted' '
|
||||||
|
echo "big QQ blue Q Q" | q_to_tab >expect &&
|
||||||
|
git config --get section.sparseAndBiggerTailQuotedPlus >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'leading and trailing whitespace' '
|
||||||
|
echo "big blue" >expect &&
|
||||||
|
git config --get section.headAndTail >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'leading and trailing whitespace, all quoted' '
|
||||||
|
echo "Qbig blue " | q_to_tab >expect &&
|
||||||
|
git config --get section.headAndTailQuoted >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'leading and trailing whitespace, not all quoted' '
|
||||||
|
echo "Qbig blue " | q_to_tab >expect &&
|
||||||
|
git config --get section.headAndTailQuotedPlus >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'inline comment' '
|
||||||
|
echo "big blue" >expect &&
|
||||||
|
git config --get section.annotated >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'inline comment, quoted' '
|
||||||
|
echo "big blue" >expect &&
|
||||||
|
git config --get section.annotatedQuoted >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'clear default config' '
|
test_expect_success 'clear default config' '
|
||||||
rm -f .git/config
|
rm -f .git/config
|
||||||
'
|
'
|
||||||
|
@ -1066,9 +1158,25 @@ test_expect_success '--null --get-regexp' '
|
||||||
test_cmp expect result
|
test_cmp expect result
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success 'inner whitespace kept verbatim' '
|
test_expect_success 'inner whitespace kept verbatim, spaces only' '
|
||||||
git config section.val "foo bar" &&
|
echo "foo bar" >expect &&
|
||||||
test_cmp_config "foo bar" section.val
|
git config section.val "foo bar" &&
|
||||||
|
git config --get section.val >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'inner whitespace kept verbatim, horizontal tabs only' '
|
||||||
|
echo "fooQQbar" | q_to_tab >expect &&
|
||||||
|
git config section.val "$(cat expect)" &&
|
||||||
|
git config --get section.val >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'inner whitespace kept verbatim, horizontal tabs and spaces' '
|
||||||
|
echo "foo Q bar" | q_to_tab >expect &&
|
||||||
|
git config section.val "$(cat expect)" &&
|
||||||
|
git config --get section.val >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
test_expect_success SYMLINKS 'symlinked configuration' '
|
test_expect_success SYMLINKS 'symlinked configuration' '
|
||||||
|
|
Loading…
Reference in New Issue