mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-23 03:18:59 +00:00
This commit is contained in:
parent
4072ae4d05
commit
17e3608865
@ -88,8 +88,20 @@ func adjustRoot(root string) string {
|
|||||||
// directory, this returns an error, to prevent accessing files that are not in the
|
// directory, this returns an error, to prevent accessing files that are not in the
|
||||||
// shared directory.
|
// shared directory.
|
||||||
func (f *BasicFilesystem) rooted(rel string) (string, error) {
|
func (f *BasicFilesystem) rooted(rel string) (string, error) {
|
||||||
|
return rooted(rel, f.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rootedSymlinkEvaluated does the same as rooted, but the returned path will not
|
||||||
|
// contain any symlinks. package. If the relative path somehow causes the final
|
||||||
|
// path to escape the root directory, this returns an error, to prevent accessing
|
||||||
|
// files that are not in the shared directory.
|
||||||
|
func (f *BasicFilesystem) rootedSymlinkEvaluated(rel string) (string, error) {
|
||||||
|
return rooted(rel, f.rootSymlinkEvaluated)
|
||||||
|
}
|
||||||
|
|
||||||
|
func rooted(rel, root string) (string, error) {
|
||||||
// The root must not be empty.
|
// The root must not be empty.
|
||||||
if f.root == "" {
|
if root == "" {
|
||||||
return "", ErrInvalidFilename
|
return "", ErrInvalidFilename
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +109,7 @@ func (f *BasicFilesystem) rooted(rel string) (string, error) {
|
|||||||
|
|
||||||
// The expected prefix for the resulting path is the root, with a path
|
// The expected prefix for the resulting path is the root, with a path
|
||||||
// separator at the end.
|
// separator at the end.
|
||||||
expectedPrefix := filepath.FromSlash(f.root)
|
expectedPrefix := filepath.FromSlash(root)
|
||||||
if !strings.HasSuffix(expectedPrefix, pathSep) {
|
if !strings.HasSuffix(expectedPrefix, pathSep) {
|
||||||
expectedPrefix += pathSep
|
expectedPrefix += pathSep
|
||||||
}
|
}
|
||||||
@ -111,7 +123,7 @@ func (f *BasicFilesystem) rooted(rel string) (string, error) {
|
|||||||
// The supposedly correct path is the one filepath.Join will return, as
|
// The supposedly correct path is the one filepath.Join will return, as
|
||||||
// it does cleaning and so on. Check that one first to make sure no
|
// it does cleaning and so on. Check that one first to make sure no
|
||||||
// obvious escape attempts have been made.
|
// obvious escape attempts have been made.
|
||||||
joined := filepath.Join(f.root, rel)
|
joined := filepath.Join(root, rel)
|
||||||
if rel == "." && !strings.HasSuffix(joined, pathSep) {
|
if rel == "." && !strings.HasSuffix(joined, pathSep) {
|
||||||
joined += pathSep
|
joined += pathSep
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ package fs
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ import (
|
|||||||
var backendBuffer = 500
|
var backendBuffer = 500
|
||||||
|
|
||||||
func (f *BasicFilesystem) Watch(name string, ignore Matcher, ctx context.Context, ignorePerms bool) (<-chan Event, error) {
|
func (f *BasicFilesystem) Watch(name string, ignore Matcher, ctx context.Context, ignorePerms bool) (<-chan Event, error) {
|
||||||
absName, err := f.rooted(name)
|
absName, err := f.rootedSymlinkEvaluated(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -110,7 +111,7 @@ func (f *BasicFilesystem) unrootedChecked(absPath string) string {
|
|||||||
return "."
|
return "."
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(absPath, f.rootSymlinkEvaluated) {
|
if !strings.HasPrefix(absPath, f.rootSymlinkEvaluated) {
|
||||||
panic("bug: Notify backend is processing a change outside of the watched path: " + absPath)
|
panic(fmt.Sprintf("bug: Notify backend is processing a change outside of the filesystem root: root==%v, rootSymEval==%v, path==%v", f.root, f.rootSymlinkEvaluated, absPath))
|
||||||
}
|
}
|
||||||
return f.unrootedSymlinkEvaluated(absPath)
|
return f.unrootedSymlinkEvaluated(absPath)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -256,6 +257,35 @@ func TestUnrootedChecked(t *testing.T) {
|
|||||||
unrooted = fs.unrootedChecked("/random/other/path")
|
unrooted = fs.unrootedChecked("/random/other/path")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWatchIssue4877(t *testing.T) {
|
||||||
|
if runtime.GOOS != "windows" {
|
||||||
|
t.Skip("Windows specific test")
|
||||||
|
}
|
||||||
|
|
||||||
|
name := "Issue4877"
|
||||||
|
|
||||||
|
file := "file"
|
||||||
|
|
||||||
|
testCase := func() {
|
||||||
|
createTestFile(name, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedEvents := []Event{
|
||||||
|
{file, NonRemove},
|
||||||
|
}
|
||||||
|
allowedEvents := []Event{
|
||||||
|
{name, NonRemove},
|
||||||
|
}
|
||||||
|
|
||||||
|
origTestFs := testFs
|
||||||
|
testFs = NewFilesystem(FilesystemTypeBasic, strings.ToLower(testDirAbs[:1])+strings.ToUpper(testDirAbs[1:]))
|
||||||
|
defer func() {
|
||||||
|
testFs = origTestFs
|
||||||
|
}()
|
||||||
|
|
||||||
|
testScenario(t, name, testCase, expectedEvents, allowedEvents, "")
|
||||||
|
}
|
||||||
|
|
||||||
// path relative to folder root, also creates parent dirs if necessary
|
// path relative to folder root, also creates parent dirs if necessary
|
||||||
func createTestFile(name string, file string) string {
|
func createTestFile(name string, file string) string {
|
||||||
joined := filepath.Join(name, file)
|
joined := filepath.Join(name, file)
|
||||||
|
Loading…
Reference in New Issue
Block a user