lib/ignore: Only skip for toplevel includes (fixes #6487) (#6508)

This commit is contained in:
Simon Frei 2020-04-07 10:23:38 +02:00 committed by GitHub
parent b64052bc26
commit 07ce3572a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 64 additions and 20 deletions

View File

@ -67,16 +67,11 @@ func (p Pattern) allowsSkippingIgnoredDirs() bool {
if p.pattern[0] != '/' { if p.pattern[0] != '/' {
return false return false
} }
// Double asterisk everywhere in the path except at the end is bad if strings.Contains(p.pattern[1:], "/") {
if strings.Contains(strings.TrimSuffix(p.pattern, "**"), "**") {
return false return false
} }
// Any wildcards anywhere except for the last path component are bad // Double asterisk everywhere in the path except at the end is bad
lastSep := strings.LastIndex(p.pattern, "/") return !strings.Contains(strings.TrimSuffix(p.pattern, "**"), "**")
if lastSep == -1 {
return true
}
return p.pattern[:lastSep] == glob.QuoteMeta(p.pattern[:lastSep])
} }
type Result uint8 type Result uint8

View File

@ -1110,10 +1110,10 @@ func TestSkipIgnoredDirs(t *testing.T) {
{`!/t*t`, true}, {`!/t*t`, true},
{`!/t?t`, true}, {`!/t?t`, true},
{`!/**`, true}, {`!/**`, true},
{`!/parent/test`, true}, {`!/parent/test`, false},
{`!/parent/t[eih]t`, true}, {`!/parent/t[eih]t`, false},
{`!/parent/t*t`, true}, {`!/parent/t*t`, false},
{`!/parent/t?t`, true}, {`!/parent/t?t`, false},
{`!/**.mp3`, false}, {`!/**.mp3`, false},
{`!/pa*nt/test`, false}, {`!/pa*nt/test`, false},
{`!/pa[sdf]nt/t[eih]t`, false}, {`!/pa[sdf]nt/t[eih]t`, false},
@ -1150,6 +1150,17 @@ func TestSkipIgnoredDirs(t *testing.T) {
if !pats.SkipIgnoredDirs() { if !pats.SkipIgnoredDirs() {
t.Error("SkipIgnoredDirs should be true") t.Error("SkipIgnoredDirs should be true")
} }
stignore = `
!/foo/ign*
*
`
if err := pats.Parse(bytes.NewBufferString(stignore), ".stignore"); err != nil {
t.Fatal(err)
}
if pats.SkipIgnoredDirs() {
t.Error("SkipIgnoredDirs should be false")
}
} }
func TestEmptyPatterns(t *testing.T) { func TestEmptyPatterns(t *testing.T) {

View File

@ -767,16 +767,10 @@ func TestNotExistingError(t *testing.T) {
} }
func TestSkipIgnoredDirs(t *testing.T) { func TestSkipIgnoredDirs(t *testing.T) {
tmp, err := ioutil.TempDir("", "") fss := fs.NewFilesystem(fs.FilesystemTypeFake, "")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmp)
fss := fs.NewFilesystem(fs.FilesystemTypeBasic, tmp)
name := "foo/ignored" name := "foo/ignored"
err = fss.MkdirAll(name, 0777) err := fss.MkdirAll(name, 0777)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -811,6 +805,50 @@ func TestSkipIgnoredDirs(t *testing.T) {
} }
} }
// https://github.com/syncthing/syncthing/issues/6487
func TestIncludedSubdir(t *testing.T) {
fss := fs.NewFilesystem(fs.FilesystemTypeFake, "")
name := filepath.Clean("foo/bar/included")
err := fss.MkdirAll(name, 0777)
if err != nil {
t.Fatal(err)
}
pats := ignore.New(fss, ignore.WithCache(true))
stignore := `
!/foo/bar
*
`
if err := pats.Parse(bytes.NewBufferString(stignore), ".stignore"); err != nil {
t.Fatal(err)
}
fchan := Walk(context.TODO(), Config{
CurrentFiler: make(fakeCurrentFiler),
Filesystem: fss,
Matcher: pats,
})
found := false
for f := range fchan {
if f.Err != nil {
t.Fatalf("Error while scanning %v: %v", f.Err, f.Path)
}
if f.File.IsIgnored() {
t.Error("File is ignored:", f.File.Name)
}
if f.File.Name == name {
found = true
}
}
if !found {
t.Errorf("File not present in scan results")
}
}
// Verify returns nil or an error describing the mismatch between the block // Verify returns nil or an error describing the mismatch between the block
// list and actual reader contents // list and actual reader contents
func verify(r io.Reader, blocksize int, blocks []protocol.BlockInfo) error { func verify(r io.Reader, blocksize int, blocks []protocol.BlockInfo) error {