浏览代码

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

Simon Frei 5 年之前
父节点
当前提交
07ce3572a0
共有 3 个文件被更改,包括 64 次插入20 次删除
  1. 3 8
      lib/ignore/ignore.go
  2. 15 4
      lib/ignore/ignore_test.go
  3. 46 8
      lib/scanner/walk_test.go

+ 3 - 8
lib/ignore/ignore.go

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

+ 15 - 4
lib/ignore/ignore_test.go

@@ -1110,10 +1110,10 @@ func TestSkipIgnoredDirs(t *testing.T) {
 		{`!/t*t`, true},
 		{`!/t?t`, true},
 		{`!/**`, true},
-		{`!/parent/test`, true},
-		{`!/parent/t[eih]t`, true},
-		{`!/parent/t*t`, true},
-		{`!/parent/t?t`, true},
+		{`!/parent/test`, false},
+		{`!/parent/t[eih]t`, false},
+		{`!/parent/t*t`, false},
+		{`!/parent/t?t`, false},
 		{`!/**.mp3`, false},
 		{`!/pa*nt/test`, false},
 		{`!/pa[sdf]nt/t[eih]t`, false},
@@ -1150,6 +1150,17 @@ func TestSkipIgnoredDirs(t *testing.T) {
 	if !pats.SkipIgnoredDirs() {
 		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) {

+ 46 - 8
lib/scanner/walk_test.go

@@ -767,16 +767,10 @@ func TestNotExistingError(t *testing.T) {
 }
 
 func TestSkipIgnoredDirs(t *testing.T) {
-	tmp, err := ioutil.TempDir("", "")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmp)
-
-	fss := fs.NewFilesystem(fs.FilesystemTypeBasic, tmp)
+	fss := fs.NewFilesystem(fs.FilesystemTypeFake, "")
 
 	name := "foo/ignored"
-	err = fss.MkdirAll(name, 0777)
+	err := fss.MkdirAll(name, 0777)
 	if err != nil {
 		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
 // list and actual reader contents
 func verify(r io.Reader, blocksize int, blocks []protocol.BlockInfo) error {