diff --git a/lib/fs/basicfs_unix.go b/lib/fs/basicfs_unix.go index eb2912cca..5571588f7 100644 --- a/lib/fs/basicfs_unix.go +++ b/lib/fs/basicfs_unix.go @@ -62,6 +62,10 @@ func (f *BasicFilesystem) Roots() ([]string, error) { // pathseparator. func (f *BasicFilesystem) unrootedChecked(absPath string, roots []string) (string, *ErrWatchEventOutsideRoot) { for _, root := range roots { + // Make sure the root ends with precisely one path separator, to + // ease prefix comparisons. + root := strings.TrimRight(root, string(PathSeparator)) + string(PathSeparator) + if absPath+string(PathSeparator) == root { return ".", nil } diff --git a/lib/fs/basicfs_watch_test.go b/lib/fs/basicfs_watch_test.go index 72eb0ae03..26b01aab3 100644 --- a/lib/fs/basicfs_watch_test.go +++ b/lib/fs/basicfs_watch_test.go @@ -201,23 +201,33 @@ func TestWatchWinRoot(t *testing.T) { // TestWatchOutside checks that no changes from outside the folder make it in func TestWatchOutside(t *testing.T) { + expectErrorForPath(t, filepath.Join(filepath.Dir(testDirAbs), "outside")) + + rootWithoutSlash := strings.TrimRight(filepath.ToSlash(testDirAbs), "/") + expectErrorForPath(t, rootWithoutSlash+"outside") + expectErrorForPath(t, rootWithoutSlash+"outside/thing") +} + +func expectErrorForPath(t *testing.T, path string) { outChan := make(chan Event) backendChan := make(chan notify.EventInfo, backendBuffer) errChan := make(chan error) ctx, cancel := context.WithCancel(context.Background()) + defer cancel() // testFs is Filesystem, but we need BasicFilesystem here fs := newBasicFilesystem(testDirAbs) go fs.watchLoop(".", []string{testDirAbs}, backendChan, outChan, errChan, fakeMatcher{}, ctx) - backendChan <- fakeEventInfo(filepath.Join(filepath.Dir(testDirAbs), "outside")) + backendChan <- fakeEventInfo(path) select { case <-time.After(10 * time.Second): - cancel() t.Errorf("Timed out before receiving error") + case e := <-outChan: + t.Errorf("Unexpected passed through event %v", e) case <-errChan: case <-ctx.Done(): }