mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-08 22:31:04 +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 {
|
||||
// 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}
|
||||
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 {
|
||||
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
|
||||
// the directory and removes them if possible or returns an error if it fails
|
||||
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)
|
||||
|
||||
toBeDeleted := make([]string, 0, len(files))
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"github.com/syncthing/syncthing/lib/events"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/ignore"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
"github.com/syncthing/syncthing/lib/scanner"
|
||||
"github.com/syncthing/syncthing/lib/sync"
|
||||
@ -124,7 +125,7 @@ func setupSendReceiveFolder(files ...protocol.FileInfo) (*model, *sendReceiveFol
|
||||
func cleanupSRFolder(f *sendReceiveFolder, m *model) {
|
||||
m.evLogger.Stop()
|
||||
os.Remove(m.cfg.ConfigPath())
|
||||
os.Remove(f.Filesystem().URI())
|
||||
os.RemoveAll(f.Filesystem().URI())
|
||||
}
|
||||
|
||||
// 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) {
|
||||
s.mut.Lock()
|
||||
defer s.mut.Unlock()
|
||||
|
Loading…
Reference in New Issue
Block a user