lib/ignore: Add central check for internal files, used in scanning, pulling and requests
GitHub-Pull-Request: https://github.com/syncthing/syncthing/pull/3779
This commit is contained in:
parent
7157917a16
commit
e3cf718998
@ -401,3 +401,20 @@ func parseIgnoreFile(fd io.Reader, currentFile string, modtimes map[string]time.
|
|||||||
|
|
||||||
return patterns, nil
|
return patterns, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsInternal returns true if the file, as a path relative to the folder
|
||||||
|
// root, represents an internal file that should always be ignored. The file
|
||||||
|
// path must be clean (i.e., in canonical shortest form).
|
||||||
|
func IsInternal(file string) bool {
|
||||||
|
internals := []string{".stfolder", ".stignore", ".stversions"}
|
||||||
|
pathSep := string(os.PathSeparator)
|
||||||
|
for _, internal := range internals {
|
||||||
|
if file == internal {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(file, internal+pathSep) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@ -812,3 +812,34 @@ func TestGobwasGlobIssue18(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsInternal(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
file string
|
||||||
|
internal bool
|
||||||
|
}{
|
||||||
|
{".stfolder", true},
|
||||||
|
{".stignore", true},
|
||||||
|
{".stversions", true},
|
||||||
|
{".stfolder/foo", true},
|
||||||
|
{".stignore/foo", true},
|
||||||
|
{".stversions/foo", true},
|
||||||
|
|
||||||
|
{".stfolderfoo", false},
|
||||||
|
{".stignorefoo", false},
|
||||||
|
{".stversionsfoo", false},
|
||||||
|
{"foo.stfolder", false},
|
||||||
|
{"foo.stignore", false},
|
||||||
|
{"foo.stversions", false},
|
||||||
|
{"foo/.stfolder", false},
|
||||||
|
{"foo/.stignore", false},
|
||||||
|
{"foo/.stversions", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range cases {
|
||||||
|
res := IsInternal(filepath.FromSlash(tc.file))
|
||||||
|
if res != tc.internal {
|
||||||
|
t.Errorf("Unexpected result: IsInteral(%q): %v should be %v", tc.file, res, tc.internal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1099,16 +1099,18 @@ func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset
|
|||||||
return protocol.ErrInvalid
|
return protocol.ErrInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
if folderIgnores != nil {
|
// Having passed the rootedJoinedPath check above, we know "name" is
|
||||||
// "rn" becomes the relative name of the file within the folder. This is
|
// acceptable relative to "folderPath" and in canonical form, so we can
|
||||||
// different than the original "name" parameter in that it's been
|
// trust it.
|
||||||
// cleaned from any possible funny business.
|
|
||||||
if rn, err := filepath.Rel(folderPath, fn); err != nil {
|
if ignore.IsInternal(name) {
|
||||||
return err
|
l.Debugf("%v REQ(in) for internal file: %s: %q / %q o=%d s=%d", m, deviceID, folder, name, offset, len(buf))
|
||||||
} else if folderIgnores.Match(rn).IsIgnored() {
|
return protocol.ErrNoSuchFile
|
||||||
l.Debugf("%v REQ(in) for ignored file: %s: %q / %q o=%d s=%d", m, deviceID, folder, name, offset, len(buf))
|
}
|
||||||
return protocol.ErrNoSuchFile
|
|
||||||
}
|
if folderIgnores.Match(name).IsIgnored() {
|
||||||
|
l.Debugf("%v REQ(in) for ignored file: %s: %q / %q o=%d s=%d", m, deviceID, folder, name, offset, len(buf))
|
||||||
|
return protocol.ErrNoSuchFile
|
||||||
}
|
}
|
||||||
|
|
||||||
if info, err := osutil.Lstat(fn); err == nil && info.Mode()&os.ModeSymlink != 0 {
|
if info, err := osutil.Lstat(fn); err == nil && info.Mode()&os.ModeSymlink != 0 {
|
||||||
@ -2483,7 +2485,7 @@ func unifySubs(dirs []string, exists func(dir string) bool) []string {
|
|||||||
func trimUntilParentKnown(dirs []string, exists func(dir string) bool) []string {
|
func trimUntilParentKnown(dirs []string, exists func(dir string) bool) []string {
|
||||||
var subs []string
|
var subs []string
|
||||||
for _, sub := range dirs {
|
for _, sub := range dirs {
|
||||||
for sub != "" && sub != ".stfolder" && sub != ".stignore" {
|
for sub != "" && !ignore.IsInternal(sub) {
|
||||||
sub = filepath.Clean(sub)
|
sub = filepath.Clean(sub)
|
||||||
parent := filepath.Dir(sub)
|
parent := filepath.Dir(sub)
|
||||||
if parent == "." || exists(parent) {
|
if parent == "." || exists(parent) {
|
||||||
@ -2545,6 +2547,9 @@ func shouldIgnore(file db.FileIntf, matcher *ignore.Matcher, ignoreDelete bool)
|
|||||||
// deleted files.
|
// deleted files.
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
case ignore.IsInternal(file.FileName()):
|
||||||
|
return true
|
||||||
|
|
||||||
case matcher.Match(file.FileName()).IsIgnored():
|
case matcher.Match(file.FileName()).IsIgnored():
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -242,13 +242,12 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
|
|||||||
}
|
}
|
||||||
|
|
||||||
info, err = w.Lstater.Lstat(absPath)
|
info, err = w.Lstater.Lstat(absPath)
|
||||||
// An error here would be weird as we've already gotten to this point, but act on it ninetheless
|
// An error here would be weird as we've already gotten to this point, but act on it nonetheless
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return skip
|
return skip
|
||||||
}
|
}
|
||||||
|
|
||||||
if w.TempNamer.IsTemporary(relPath) {
|
if w.TempNamer.IsTemporary(relPath) {
|
||||||
// A temporary file
|
|
||||||
l.Debugln("temporary:", relPath)
|
l.Debugln("temporary:", relPath)
|
||||||
if info.Mode().IsRegular() && info.ModTime().Add(w.TempLifetime).Before(now) {
|
if info.Mode().IsRegular() && info.ModTime().Add(w.TempLifetime).Before(now) {
|
||||||
os.Remove(absPath)
|
os.Remove(absPath)
|
||||||
@ -257,10 +256,13 @@ func (w *walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if sn := filepath.Base(relPath); sn == ".stignore" || sn == ".stfolder" ||
|
if ignore.IsInternal(relPath) {
|
||||||
strings.HasPrefix(relPath, ".stversions") || (w.Matcher != nil && w.Matcher.Match(relPath).IsIgnored()) {
|
l.Debugln("ignored (internal):", relPath)
|
||||||
// An ignored file
|
return skip
|
||||||
l.Debugln("ignored:", relPath)
|
}
|
||||||
|
|
||||||
|
if w.Matcher.Match(relPath).IsIgnored() {
|
||||||
|
l.Debugln("ignored (patterns):", relPath)
|
||||||
return skip
|
return skip
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user