diff --git a/lib/model/model.go b/lib/model/model.go index d1cb73c5..574915c8 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -122,7 +122,6 @@ var ( errDeviceIgnored = errors.New("device is ignored") errNotRelative = errors.New("not a relative path") errNotDir = errors.New("parent is not a directory") - errNameConflict = errors.New("filename collides with existing file") ) // NewModel creates and starts a new model. The model starts in read-only mode, @@ -1160,11 +1159,6 @@ func (m *Model) Request(deviceID protocol.DeviceID, folder, name string, offset return protocol.ErrNoSuchFile } - if !osutil.CheckNameConflict(folderPath, name) { - l.Debugf("%v REQ(in) for file not in dir: %s: %q / %q o=%d s=%d", m, deviceID, folder, name, offset, len(buf)) - return protocol.ErrNoSuchFile - } - // Only check temp files if the flag is set, and if we are set to advertise // the temp indexes. if fromTemporary && !folderCfg.DisableTempIndexes { @@ -1902,12 +1896,7 @@ func (m *Model) internalScanFolderSubdirs(folder string, subDirs []string) error // The file is valid and not deleted. Lets check if it's // still here. - var exists bool - if !osutil.IsDir(folderCfg.Path(), filepath.Dir(f.Name)) { - exists = false - } else if !osutil.CheckNameConflict(folderCfg.Path(), f.Name) { - exists = false - } else if _, err := mtimefs.Lstat(filepath.Join(folderCfg.Path(), f.Name)); err != nil { + if _, err := mtimefs.Lstat(filepath.Join(folderCfg.Path(), f.Name)); err != nil { // We don't specifically verify that the error is // os.IsNotExist because there is a corner case when a // directory is suddenly transformed into a file. When that @@ -1915,11 +1904,6 @@ func (m *Model) internalScanFolderSubdirs(folder string, subDirs []string) error // file) are deleted but will return a confusing error ("not a // directory") when we try to Lstat() them. - exists = false - } else { - exists = true - } - if !exists { nf := protocol.FileInfo{ Name: f.Name, Type: f.Type, diff --git a/lib/model/rwfolder.go b/lib/model/rwfolder.go index ad9b56b7..fab982b9 100644 --- a/lib/model/rwfolder.go +++ b/lib/model/rwfolder.go @@ -435,13 +435,6 @@ func (f *sendReceiveFolder) pullerIteration(ignores *ignore.Matcher) int { continue } - // Verify that we handle the right thing and not something whose name - // collides. - if !osutil.CheckNameConflict(f.dir, fi.Name) { - f.newError(fi.Name, errNameConflict) - continue - } - switch { case fi.IsDeleted(): // A deleted file, directory or symlink @@ -531,13 +524,6 @@ nextFile: continue } - // Verify that we handle the right thing and not something whose name - // collides. - if !osutil.CheckNameConflict(f.dir, fi.Name) { - f.newError(fi.Name, errNameConflict) - continue - } - // Check our list of files to be removed for a match, in which case // we can just do a rename instead. key := string(fi.Blocks[0].Hash) @@ -1287,16 +1273,6 @@ func (f *sendReceiveFolder) copierRoutine(in <-chan copyBlocksState, pullChan ch if err != nil { return false } - // The following checks are racy - if !osutil.IsDir(folderRoots[folder], filepath.Dir(file)) { - return false - } - if !osutil.CheckNameConflict(folderRoots[folder], file) { - return false - } - if info, err := osutil.Lstat(inFile); err != nil || !info.Mode().IsRegular() { - return false - } fd, err := os.Open(inFile) if err != nil { return false diff --git a/lib/osutil/name_conflict.go b/lib/osutil/name_conflict.go deleted file mode 100644 index a3edd8f0..00000000 --- a/lib/osutil/name_conflict.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2016 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -// +build !windows - -package osutil - -// CheckNameConflict returns true if every path component of name up to and -// including filepath.Join(base, name) doesn't conflict with any existing -// files or folders with different names. Base and name must both be clean and -// name must be relative to base. -func CheckNameConflict(base, name string) bool { - return true -} diff --git a/lib/osutil/name_conflict_windows.go b/lib/osutil/name_conflict_windows.go deleted file mode 100644 index 1014c92e..00000000 --- a/lib/osutil/name_conflict_windows.go +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2016 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -// +build windows - -package osutil - -import ( - "os" - "path/filepath" - "strings" - "syscall" -) - -// CheckNameConflict returns true if every path component of name up to and -// including filepath.Join(base, name) doesn't conflict with any existing -// files or folders with different names. Base and name must both be clean and -// name must be relative to base. -func CheckNameConflict(base, name string) bool { - // Conflicts can be caused by different casing (e.g. foo and FOO) or - // by the use of short names (e.g. foo.barbaz and FOO~1.BAR). - path := base - parts := strings.Split(name, string(os.PathSeparator)) - for _, part := range parts { - path = filepath.Join(path, part) - pathp, err := syscall.UTF16PtrFromString(path) - if err != nil { - return false - } - var data syscall.Win32finddata - handle, err := syscall.FindFirstFile(pathp, &data) - if err == syscall.ERROR_FILE_NOT_FOUND { - return true - } - if err != nil { - return false - } - syscall.FindClose(handle) - fileName := syscall.UTF16ToString(data.FileName[:]) - if part != fileName { - return false - } - } - return true -} diff --git a/lib/osutil/name_conflict_windows_test.go b/lib/osutil/name_conflict_windows_test.go deleted file mode 100644 index f8e6aace..00000000 --- a/lib/osutil/name_conflict_windows_test.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2016 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -// +build windows - -package osutil_test - -import ( - "os" - "path" - "path/filepath" - "syscall" - "testing" - "unsafe" - - "github.com/syncthing/syncthing/lib/osutil" -) - -func TestCheckNameConflictCasing(t *testing.T) { - os.RemoveAll("testdata") - defer os.RemoveAll("testdata") - os.MkdirAll("testdata/Foo/BAR/baz", 0755) - // check if the file system is case-sensitive - if _, err := os.Lstat("testdata/foo"); err != nil { - t.Skip("pointless test") - return - } - - cases := []struct { - name string - conflictFree bool - }{ - // Exists - {"Foo", true}, - {"Foo/BAR", true}, - {"Foo/BAR/baz", true}, - // Doesn't exist - {"bar", true}, - {"Foo/baz", true}, - // Conflicts - {"foo", false}, - {"foo/BAR", false}, - {"Foo/bar", false}, - {"Foo/BAR/BAZ", false}, - } - - for _, tc := range cases { - nativeName := filepath.FromSlash(tc.name) - if res := osutil.CheckNameConflict("testdata", nativeName); res != tc.conflictFree { - t.Errorf("CheckNameConflict(%q) = %v, should be %v", tc.name, res, tc.conflictFree) - } - } -} - -func TestCheckNameConflictShortName(t *testing.T) { - os.RemoveAll("testdata") - defer os.RemoveAll("testdata") - os.MkdirAll("testdata/foobarbaz/qux", 0755) - ppath, err := syscall.UTF16PtrFromString("testdata/foobarbaz") - if err != nil { - t.Fatal("unexpected error", err) - } - // check if the file system supports short names - bufferSize, err := syscall.GetShortPathName(ppath, nil, 0) - if err != nil { - t.Skip("pointless test") - return - } - - // get the short name - buffer := make([]uint16, bufferSize) - length, err := syscall.GetShortPathName(ppath, - (*uint16)(unsafe.Pointer(&buffer[0])), bufferSize) - if err != nil { - t.Fatal("unexpected error", err) - } - // on success length doesn't contain the terminating null character - if bufferSize != length+1 { - t.Fatal("length of short name changed") - } - shortName := filepath.Base(syscall.UTF16ToString(buffer)) - - cases := []struct { - name string - conflictFree bool - }{ - // Exists - {"foobarbaz", true}, - {"foobarbaz/qux", true}, - // Doesn't exist - {"foo", true}, - {"foobarbaz/quux", true}, - // Conflicts - {shortName, false}, - {path.Join(shortName, "qux"), false}, - {path.Join(shortName, "quux"), false}, - } - - for _, tc := range cases { - nativeName := filepath.FromSlash(tc.name) - if res := osutil.CheckNameConflict("testdata", nativeName); res != tc.conflictFree { - t.Errorf("CheckNameConflict(%q) = %v, should be %v", tc.name, res, tc.conflictFree) - } - } -} diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index dff4751d..7017508f 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -130,14 +130,6 @@ func (w *walker) walk() (chan protocol.FileInfo, error) { filepath.Walk(w.Dir, hashFiles) } else { for _, sub := range w.Subs { - if !osutil.IsDir(w.Dir, filepath.Dir(sub)) { - l.Infoln("Skipping sub path that is not in a directory", w.Dir, sub) - continue - } - if !osutil.CheckNameConflict(w.Dir, sub) { - l.Infoln("Skipping sub path that collides", w.Dir, sub) - continue - } filepath.Walk(filepath.Join(w.Dir, sub), hashFiles) } }