From 2f9840ddae38974684c25154352fde89bdd0e3e8 Mon Sep 17 00:00:00 2001 From: Simon Frei Date: Thu, 22 Nov 2018 11:16:45 +0100 Subject: [PATCH] lib: Introduce fs.IsParent (fixes #5324) (#5326) --- lib/fs/filesystem.go | 3 +-- lib/fs/util.go | 12 ++++++++++++ lib/ignore/ignore.go | 2 +- lib/model/folder.go | 9 +++------ lib/model/model.go | 2 +- lib/scanner/walk.go | 2 +- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/fs/filesystem.go b/lib/fs/filesystem.go index 4449b94e..ce2aa437 100644 --- a/lib/fs/filesystem.go +++ b/lib/fs/filesystem.go @@ -199,12 +199,11 @@ func NewFilesystem(fsType FilesystemType, uri string) Filesystem { func IsInternal(file string) bool { // fs cannot import config, so we hard code .stfolder here (config.DefaultMarkerName) internals := []string{".stfolder", ".stignore", ".stversions"} - pathSep := string(PathSeparator) for _, internal := range internals { if file == internal { return true } - if strings.HasPrefix(file, internal+pathSep) { + if IsParent(file, internal) { return true } } diff --git a/lib/fs/util.go b/lib/fs/util.go index 5c8be8e5..3c44d3c9 100644 --- a/lib/fs/util.go +++ b/lib/fs/util.go @@ -77,3 +77,15 @@ func WindowsInvalidFilename(name string) bool { // The path must not contain any disallowed characters return strings.ContainsAny(name, windowsDisallowedCharacters) } + +func IsParent(path, parent string) bool { + if len(parent) == 0 { + // The empty string is the parent of everything except the empty + // string. (Avoids panic in the next step.) + return len(path) > 0 + } + if parent[len(parent)-1] != PathSeparator { + parent += string(PathSeparator) + } + return strings.HasPrefix(path, parent) +} diff --git a/lib/ignore/ignore.go b/lib/ignore/ignore.go index 181a804a..74d35c1e 100644 --- a/lib/ignore/ignore.go +++ b/lib/ignore/ignore.go @@ -336,7 +336,7 @@ func loadParseIncludeFile(filesystem fs.Filesystem, file string, cd ChangeDetect if filesystem.Type() == fs.FilesystemTypeBasic { uri := filesystem.URI() joined := filepath.Join(uri, file) - if !strings.HasPrefix(joined, uri) { + if !fs.IsParent(joined, uri) { filesystem = fs.NewFilesystem(filesystem.Type(), filepath.Dir(joined)) file = filepath.Base(joined) } diff --git a/lib/model/folder.go b/lib/model/folder.go index 88ae5717..c44a7432 100644 --- a/lib/model/folder.go +++ b/lib/model/folder.go @@ -13,7 +13,6 @@ import ( "math/rand" "path/filepath" "sort" - "strings" "sync/atomic" "time" @@ -411,7 +410,6 @@ func (f *folder) scanSubdirs(subDirs []string) error { // ignored files. var toIgnore []db.FileInfoTruncated ignoredParent := "" - pathSep := string(fs.PathSeparator) for _, sub := range subDirs { var iterError error @@ -423,7 +421,7 @@ func (f *folder) scanSubdirs(subDirs []string) error { return false } - if ignoredParent != "" && !strings.HasPrefix(file.Name, ignoredParent+pathSep) { + if ignoredParent != "" && !fs.IsParent(file.Name, ignoredParent) { for _, file := range toIgnore { l.Debugln("marking file as ignored", file) nf := file.ConvertToIgnoredFileInfo(f.model.id.Short()) @@ -698,11 +696,10 @@ func (f *folder) clearScanErrors(subDirs []string) { return } filtered := f.scanErrors[:0] - pathSep := string(fs.PathSeparator) outer: for _, fe := range f.scanErrors { for _, sub := range subDirs { - if strings.HasPrefix(fe.Path, sub+pathSep) { + if fe.Path == sub || fs.IsParent(fe.Path, sub) { continue outer } } @@ -735,7 +732,7 @@ func unifySubs(dirs []string, exists func(dir string) bool) []string { dirs = append(dirs[:i], dirs[i+1:]...) continue } - if dir == prev || strings.HasPrefix(dir, prev+string(fs.PathSeparator)) { + if dir == prev || fs.IsParent(dir, prev) { dirs = append(dirs[:i], dirs[i+1:]...) continue } diff --git a/lib/model/model.go b/lib/model/model.go index 7502c64d..459ff227 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -288,7 +288,7 @@ func (m *Model) warnAboutOverwritingProtectedFiles(folder string) { var filesAtRisk []string for _, protectedFilePath := range m.protectedFiles { // check if file is synced in this folder - if !strings.HasPrefix(protectedFilePath, folderLocation) { + if protectedFilePath != folderLocation && !fs.IsParent(protectedFilePath, folderLocation) { continue } diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 3b842c70..eb8f2a4d 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -250,7 +250,7 @@ func (w *walker) walkAndHashFiles(ctx context.Context, toHashChan chan<- protoco return skip } // If the parent wasn't ignored already, set this path as the "highest" ignored parent - if info.IsDir() && (ignoredParent == "" || !strings.HasPrefix(path, ignoredParent+string(fs.PathSeparator))) { + if info.IsDir() && (ignoredParent == "" || !fs.IsParent(path, ignoredParent)) { ignoredParent = path } return nil