summaryrefslogtreecommitdiff
path: root/src/attr_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/attr_file.c')
-rw-r--r--src/attr_file.c30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/attr_file.c b/src/attr_file.c
index 673f9a406..5b1007ee5 100644
--- a/src/attr_file.c
+++ b/src/attr_file.c
@@ -587,6 +587,7 @@ int git_attr_fnmatch__parse(
{
const char *pattern, *scan;
int slash_count, allow_space;
+ bool escaped;
assert(spec && base && *base);
@@ -623,28 +624,29 @@ int git_attr_fnmatch__parse(
}
slash_count = 0;
+ escaped = false;
+ /* Scan until a non-escaped whitespace. */
for (scan = pattern; *scan != '\0'; ++scan) {
- /*
- * Scan until a non-escaped whitespace: find a whitespace, then look
- * one char backward to ensure that it's not prefixed by a `\`.
- * Only look backward if we're not at the first position (`pattern`).
- */
- if (git__isspace(*scan) && scan > pattern && *(scan - 1) != '\\') {
- if (!allow_space || (*scan != ' ' && *scan != '\t' && *scan != '\r'))
- break;
- }
+ char c = *scan;
- if (*scan == '/') {
+ if (c == '\\' && !escaped) {
+ escaped = true;
+ continue;
+ } else if (git__isspace(c) && !escaped) {
+ if (!allow_space || (c != ' ' && c != '\t' && c != '\r'))
+ break;
+ } else if (c == '/') {
spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
slash_count++;
if (slash_count == 1 && pattern == scan)
pattern++;
- }
- /* remember if we see an unescaped wildcard in pattern */
- else if (git__iswildcard(*scan) &&
- (scan == pattern || (*(scan - 1) != '\\')))
+ } else if (git__iswildcard(c) && !escaped) {
+ /* remember if we see an unescaped wildcard in pattern */
spec->flags = spec->flags | GIT_ATTR_FNMATCH_HASWILD;
+ }
+
+ escaped = false;
}
*base = scan;