mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-09 23:00:58 +00:00
Correctly handle (?i) in ignores (fixes #1953)
This commit is contained in:
parent
70b37dc469
commit
e3e1036dda
@ -38,14 +38,6 @@ func Convert(pattern string, flags int) (*regexp.Regexp, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support case insensitive ignores. We do the loop because we may in some
|
|
||||||
// circumstances end up with multiple insensitivity prefixes
|
|
||||||
// ("(?i)(?i)foo"), which should be accepted.
|
|
||||||
for ignore := strings.TrimPrefix(pattern, "(?i)"); ignore != pattern; ignore = strings.TrimPrefix(pattern, "(?i)") {
|
|
||||||
flags |= CaseFold
|
|
||||||
pattern = ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags&NoEscape != 0 {
|
if flags&NoEscape != 0 {
|
||||||
pattern = strings.Replace(pattern, "\\", "\\\\", -1)
|
pattern = strings.Replace(pattern, "\\", "\\\\", -1)
|
||||||
} else {
|
} else {
|
||||||
|
@ -53,10 +53,6 @@ var testcases = []testcase{
|
|||||||
{"**/foo.txt", "bar/baz/foo.txt", PathName, true},
|
{"**/foo.txt", "bar/baz/foo.txt", PathName, true},
|
||||||
|
|
||||||
{"foo.txt", "foo.TXT", CaseFold, true},
|
{"foo.txt", "foo.TXT", CaseFold, true},
|
||||||
{"(?i)foo.txt", "foo.TXT", 0, true},
|
|
||||||
{"(?i)(?i)foo.txt", "foo.TXT", 0, true}, // repeated prefix should be fine
|
|
||||||
{"(?i)**foo.txt", "/dev/tmp/foo.TXT", 0, true},
|
|
||||||
{"(?i)!**foo.txt", "/dev/tmp/foo.TXT", 0, false},
|
|
||||||
|
|
||||||
// These characters are literals in glob, but not in regexp.
|
// These characters are literals in glob, but not in regexp.
|
||||||
{"hey$hello", "hey$hello", 0, true},
|
{"hey$hello", "hey$hello", 0, true},
|
||||||
|
@ -206,22 +206,28 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]
|
|||||||
include = false
|
include = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flags := fnmatch.PathName
|
||||||
|
if strings.HasPrefix(line, "(?i)") {
|
||||||
|
line = line[4:]
|
||||||
|
flags |= fnmatch.CaseFold
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(line, "/") {
|
if strings.HasPrefix(line, "/") {
|
||||||
// Pattern is rooted in the current dir only
|
// Pattern is rooted in the current dir only
|
||||||
exp, err := fnmatch.Convert(line[1:], fnmatch.PathName)
|
exp, err := fnmatch.Convert(line[1:], flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
||||||
}
|
}
|
||||||
patterns = append(patterns, Pattern{exp, include})
|
patterns = append(patterns, Pattern{exp, include})
|
||||||
} else if strings.HasPrefix(line, "**/") {
|
} else if strings.HasPrefix(line, "**/") {
|
||||||
// Add the pattern as is, and without **/ so it matches in current dir
|
// Add the pattern as is, and without **/ so it matches in current dir
|
||||||
exp, err := fnmatch.Convert(line, fnmatch.PathName)
|
exp, err := fnmatch.Convert(line, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
||||||
}
|
}
|
||||||
patterns = append(patterns, Pattern{exp, include})
|
patterns = append(patterns, Pattern{exp, include})
|
||||||
|
|
||||||
exp, err = fnmatch.Convert(line[3:], fnmatch.PathName)
|
exp, err = fnmatch.Convert(line[3:], flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
||||||
}
|
}
|
||||||
@ -236,13 +242,13 @@ func parseIgnoreFile(fd io.Reader, currentFile string, seen map[string]bool) ([]
|
|||||||
} else {
|
} else {
|
||||||
// Path name or pattern, add it so it matches files both in
|
// Path name or pattern, add it so it matches files both in
|
||||||
// current directory and subdirs.
|
// current directory and subdirs.
|
||||||
exp, err := fnmatch.Convert(line, fnmatch.PathName)
|
exp, err := fnmatch.Convert(line, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
||||||
}
|
}
|
||||||
patterns = append(patterns, Pattern{exp, include})
|
patterns = append(patterns, Pattern{exp, include})
|
||||||
|
|
||||||
exp, err = fnmatch.Convert("**/"+line, fnmatch.PathName)
|
exp, err = fnmatch.Convert("**/"+line, flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
return fmt.Errorf("Invalid pattern %q in ignore file", line)
|
||||||
}
|
}
|
||||||
|
@ -31,10 +31,17 @@ func TestIgnores(t *testing.T) {
|
|||||||
|
|
||||||
// Create eight empty files and directories
|
// Create eight empty files and directories
|
||||||
|
|
||||||
files := []string{"f1", "f2", "f3", "f4", "f11", "f12", "f13", "f14"}
|
|
||||||
dirs := []string{"d1", "d2", "d3", "d4", "d11", "d12", "d13", "d14"}
|
dirs := []string{"d1", "d2", "d3", "d4", "d11", "d12", "d13", "d14"}
|
||||||
|
files := []string{"f1", "f2", "f3", "f4", "f11", "f12", "f13", "f14", "d1/f1.TXT"}
|
||||||
all := append(files, dirs...)
|
all := append(files, dirs...)
|
||||||
|
|
||||||
|
for _, dir := range dirs {
|
||||||
|
err := os.Mkdir(filepath.Join("s1", dir), 0755)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
fd, err := os.Create(filepath.Join("s1", file))
|
fd, err := os.Create(filepath.Join("s1", file))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -43,13 +50,6 @@ func TestIgnores(t *testing.T) {
|
|||||||
fd.Close()
|
fd.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, dir := range dirs {
|
|
||||||
err := os.Mkdir(filepath.Join("s1", dir), 0755)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var syms []string
|
var syms []string
|
||||||
if symlinksSupported() {
|
if symlinksSupported() {
|
||||||
syms = []string{"s1", "s2", "s3", "s4", "s11", "s12", "s13", "s14"}
|
syms = []string{"s1", "s2", "s3", "s4", "s11", "s12", "s13", "s14"}
|
||||||
@ -81,7 +81,7 @@ func TestIgnores(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, err = fd.WriteString("f1*\nf2\nd1*\nd2\ns1*\ns2") // [fds][34] only non-ignored items
|
_, err = fd.WriteString("f1*\nf2\nd1*\nd2\ns1*\ns2\n(?i)*.txt") // [fds][34] only non-ignored items
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ func TestIgnores(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
expected = len(all) * 7 / 8 // seven out of eight items of each type should remain
|
expected = len(all)*7/8 + 1 // seven out of eight items of each type should remain, plus the foo.TXT
|
||||||
if m.LocalFiles != expected {
|
if m.LocalFiles != expected {
|
||||||
t.Fatalf("Incorrect number of files after second ignore, %d != %d", m.LocalFiles, expected)
|
t.Fatalf("Incorrect number of files after second ignore, %d != %d", m.LocalFiles, expected)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user