Commit b3b6a39d by Patrick Steinhardt

attr_file: account for escaped escapes when searching trailing space

When determining the trailing space length, we need to honor
whether spaces are escaped or not. Currently, we do not check
whether the escape itself is escaped, though, which might
generate an off-by-one in that case as we will simply treat the
space as escaped.

Fix this by checking whether the backslashes preceding the space
are themselves escaped.
parent 10ac298c
......@@ -565,10 +565,22 @@ void git_attr_path__free(git_attr_path *info)
*/
static size_t trailing_space_length(const char *p, size_t len)
{
size_t n;
size_t n, i;
for (n = len; n; n--) {
if ((p[n-1] != ' ' && p[n-1] != '\t') ||
(n > 1 && p[n-2] == '\\'))
if (p[n-1] != ' ' && p[n-1] != '\t')
break;
/*
* Count escape-characters before space. In case where it's an
* even number of escape characters, then the escape char itself
* is escaped and the whitespace is an unescaped whitespace.
* Otherwise, the last escape char is not escaped and the
* whitespace in an escaped whitespace.
*/
i = n;
while (i > 1 && p[i-2] == '\\')
i--;
if ((n - i) % 2)
break;
}
return len - n;
......
......@@ -521,3 +521,20 @@ void test_ignore_path__escaped_slash(void)
assert_is_ignored(true, "inter\\mittent");
assert_is_ignored(true, "trailing\\");
}
void test_ignore_path__escaped_space(void)
{
cl_git_rewritefile(
"attr/.gitignore",
"foo\\\\ \n"
"bar\\\\\\ \n");
assert_is_ignored(true, "foo\\");
assert_is_ignored(false, "foo\\ ");
assert_is_ignored(false, "foo\\\\ ");
assert_is_ignored(false, "foo\\\\");
assert_is_ignored(true, "bar\\ ");
assert_is_ignored(false, "bar\\\\");
assert_is_ignored(false, "bar\\\\ ");
assert_is_ignored(false, "bar\\\\\\");
assert_is_ignored(false, "bar\\\\\\ ");
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment