diff --git a/lib/model/model.go b/lib/model/model.go index dfc08c7c..3a84be8a 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -1705,8 +1705,16 @@ func (m *Model) ScanFolderSubdirs(folder string, subs []string) error { } func (m *Model) internalScanFolderSubdirs(folder string, subDirs []string) error { - for i, sub := range subDirs { - sub = osutil.NativeFilename(sub) + for i := 0; i < len(subDirs); i++ { + sub := osutil.NativeFilename(subDirs[i]) + + if sub == "" { + // A blank subdirs means to scan the entire folder. We can trim + // the subDirs list and go on our way. + subDirs = nil + break + } + // We test each path by joining with "root". What we join with is // not relevant, we just want the dotdot escape detection here. For // historical reasons we may get paths that end in a slash. We diff --git a/lib/model/model_test.go b/lib/model/model_test.go index 27fdaffd..7cc2626a 100644 --- a/lib/model/model_test.go +++ b/lib/model/model_test.go @@ -2181,6 +2181,21 @@ func TestIssue3804(t *testing.T) { } } +func TestIssue3829(t *testing.T) { + dbi := db.OpenMemory() + m := NewModel(defaultConfig, protocol.LocalDeviceID, "device", "syncthing", "dev", dbi, nil) + m.AddFolder(defaultFolderConfig) + m.StartFolder("default") + m.ServeBackground() + defer m.Stop() + + // Empty subdirs should be accepted + + if err := m.ScanFolderSubdirs("default", []string{""}); err != nil { + t.Error("Unexpected error:", err) + } +} + func TestRootedJoinedPath(t *testing.T) { type testcase struct { root string