mirror of
https://github.com/octoleo/syncthing.git
synced 2025-01-05 08:02:13 +00:00
This commit is contained in:
parent
72f26c1e45
commit
bbdda059bd
@ -847,10 +847,17 @@ func (f *sendReceiveFolder) deleteFileWithCurrent(file, cur protocol.FileInfo, h
|
|||||||
|
|
||||||
if !hasCur {
|
if !hasCur {
|
||||||
// We should never try to pull a deletion for a file we don't have in the DB.
|
// We should never try to pull a deletion for a file we don't have in the DB.
|
||||||
l.Debugln(f, "not deleting file we don't have", file.Name)
|
l.Debugln(f, "not deleting file we don't have, but update db", file.Name)
|
||||||
dbUpdateChan <- dbUpdateJob{file, dbUpdateDeleteFile}
|
dbUpdateChan <- dbUpdateJob{file, dbUpdateDeleteFile}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err = osutil.TraversesSymlink(f.fs, filepath.Dir(file.Name)); err != nil {
|
||||||
|
l.Debugln(f, "not deleting file behind symlink on disk, but update db", file.Name)
|
||||||
|
dbUpdateChan <- dbUpdateJob{file, dbUpdateDeleteFile}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if err = f.checkToBeDeleted(cur, scanChan); err != nil {
|
if err = f.checkToBeDeleted(cur, scanChan); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1839,6 +1846,10 @@ func (f *sendReceiveFolder) deleteItemOnDisk(item protocol.FileInfo, scanChan ch
|
|||||||
// deleteDirOnDisk attempts to delete a directory. It checks for files/dirs inside
|
// deleteDirOnDisk attempts to delete a directory. It checks for files/dirs inside
|
||||||
// the directory and removes them if possible or returns an error if it fails
|
// the directory and removes them if possible or returns an error if it fails
|
||||||
func (f *sendReceiveFolder) deleteDirOnDisk(dir string, scanChan chan<- string) error {
|
func (f *sendReceiveFolder) deleteDirOnDisk(dir string, scanChan chan<- string) error {
|
||||||
|
if err := osutil.TraversesSymlink(f.fs, filepath.Dir(dir)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
files, _ := f.fs.DirNames(dir)
|
files, _ := f.fs.DirNames(dir)
|
||||||
|
|
||||||
toBeDeleted := make([]string, 0, len(files))
|
toBeDeleted := make([]string, 0, len(files))
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/syncthing/syncthing/lib/events"
|
"github.com/syncthing/syncthing/lib/events"
|
||||||
"github.com/syncthing/syncthing/lib/fs"
|
"github.com/syncthing/syncthing/lib/fs"
|
||||||
"github.com/syncthing/syncthing/lib/ignore"
|
"github.com/syncthing/syncthing/lib/ignore"
|
||||||
|
"github.com/syncthing/syncthing/lib/osutil"
|
||||||
"github.com/syncthing/syncthing/lib/protocol"
|
"github.com/syncthing/syncthing/lib/protocol"
|
||||||
"github.com/syncthing/syncthing/lib/scanner"
|
"github.com/syncthing/syncthing/lib/scanner"
|
||||||
"github.com/syncthing/syncthing/lib/sync"
|
"github.com/syncthing/syncthing/lib/sync"
|
||||||
@ -124,7 +125,7 @@ func setupSendReceiveFolder(files ...protocol.FileInfo) (*model, *sendReceiveFol
|
|||||||
func cleanupSRFolder(f *sendReceiveFolder, m *model) {
|
func cleanupSRFolder(f *sendReceiveFolder, m *model) {
|
||||||
m.evLogger.Stop()
|
m.evLogger.Stop()
|
||||||
os.Remove(m.cfg.ConfigPath())
|
os.Remove(m.cfg.ConfigPath())
|
||||||
os.Remove(f.Filesystem().URI())
|
os.RemoveAll(f.Filesystem().URI())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout of the files: (indexes from the above array)
|
// Layout of the files: (indexes from the above array)
|
||||||
@ -907,6 +908,58 @@ func TestSRConflictReplaceFileByLink(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestDeleteBehindSymlink checks that we don't delete or schedule a scan
|
||||||
|
// when trying to delete a file behind a symlink.
|
||||||
|
func TestDeleteBehindSymlink(t *testing.T) {
|
||||||
|
m, f := setupSendReceiveFolder()
|
||||||
|
defer cleanupSRFolder(f, m)
|
||||||
|
ffs := f.Filesystem()
|
||||||
|
|
||||||
|
destDir := createTmpDir()
|
||||||
|
defer os.RemoveAll(destDir)
|
||||||
|
destFs := fs.NewFilesystem(fs.FilesystemTypeBasic, destDir)
|
||||||
|
|
||||||
|
link := "link"
|
||||||
|
file := filepath.Join(link, "file")
|
||||||
|
|
||||||
|
must(t, ffs.MkdirAll(link, 0755))
|
||||||
|
fi := createFile(t, file, ffs)
|
||||||
|
f.updateLocalsFromScanning([]protocol.FileInfo{fi})
|
||||||
|
must(t, osutil.RenameOrCopy(ffs, destFs, file, "file"))
|
||||||
|
must(t, ffs.RemoveAll(link))
|
||||||
|
|
||||||
|
if err := osutil.DebugSymlinkForTestsOnly(destFs.URI(), filepath.Join(ffs.URI(), link)); err != nil {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
// Probably we require permissions we don't have.
|
||||||
|
t.Skip("Need admin permissions or developer mode to run symlink test on Windows: " + err.Error())
|
||||||
|
} else {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fi.Deleted = true
|
||||||
|
fi.Version = fi.Version.Update(device1.Short())
|
||||||
|
scanChan := make(chan string, 1)
|
||||||
|
dbUpdateChan := make(chan dbUpdateJob, 1)
|
||||||
|
f.deleteFile(fi, dbUpdateChan, scanChan)
|
||||||
|
select {
|
||||||
|
case f := <-scanChan:
|
||||||
|
t.Fatalf("Received %v on scanChan", f)
|
||||||
|
case u := <-dbUpdateChan:
|
||||||
|
if u.jobType != dbUpdateDeleteFile {
|
||||||
|
t.Errorf("Expected jobType %v, got %v", dbUpdateDeleteFile, u.jobType)
|
||||||
|
}
|
||||||
|
if u.file.Name != fi.Name {
|
||||||
|
t.Errorf("Expected update for %v, got %v", fi.Name, u.file.Name)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
t.Fatalf("No db update received")
|
||||||
|
}
|
||||||
|
if _, err := destFs.Stat("file"); err != nil {
|
||||||
|
t.Errorf("Expected no error when stating file behind symlink, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func cleanupSharedPullerState(s *sharedPullerState) {
|
func cleanupSharedPullerState(s *sharedPullerState) {
|
||||||
s.mut.Lock()
|
s.mut.Lock()
|
||||||
defer s.mut.Unlock()
|
defer s.mut.Unlock()
|
||||||
|
Loading…
Reference in New Issue
Block a user