lib/config: Error on empty folder path (fixes #5853) (#5854)

This commit is contained in:
Simon Frei 2019-07-14 11:03:14 +02:00 committed by Jakob Borg
parent f1a7dd766e
commit def4b8cee5
8 changed files with 39 additions and 28 deletions

View File

@ -666,7 +666,10 @@ func TestConfigPostOK(t *testing.T) {
cfg := bytes.NewBuffer([]byte(`{ cfg := bytes.NewBuffer([]byte(`{
"version": 15, "version": 15,
"folders": [ "folders": [
{"id": "foo"} {
"id": "foo",
"path": "TestConfigPostOK"
}
] ]
}`)) }`))
@ -677,6 +680,7 @@ func TestConfigPostOK(t *testing.T) {
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
t.Error("Expected 200 OK, not", resp.Status) t.Error("Expected 200 OK, not", resp.Status)
} }
os.RemoveAll("TestConfigPostOK")
} }
func TestConfigPostDupFolder(t *testing.T) { func TestConfigPostDupFolder(t *testing.T) {

View File

@ -10,6 +10,7 @@ package config
import ( import (
"encoding/json" "encoding/json"
"encoding/xml" "encoding/xml"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -91,6 +92,12 @@ var (
} }
) )
var (
errFolderIDEmpty = errors.New("folder has empty ID")
errFolderIDDuplicate = errors.New("folder has duplicate ID")
errFolderPathEmpty = errors.New("folder has empty path")
)
func New(myID protocol.DeviceID) Configuration { func New(myID protocol.DeviceID) Configuration {
var cfg Configuration var cfg Configuration
cfg.Version = CurrentVersion cfg.Version = CurrentVersion
@ -273,12 +280,17 @@ func (cfg *Configuration) clean() error {
folder.prepare() folder.prepare()
if folder.ID == "" { if folder.ID == "" {
return fmt.Errorf("folder with empty ID in configuration") return errFolderIDEmpty
}
if folder.Path == "" {
return fmt.Errorf("folder %q: %v", folder.ID, errFolderPathEmpty)
} }
if _, ok := existingFolders[folder.ID]; ok { if _, ok := existingFolders[folder.ID]; ok {
return fmt.Errorf("duplicate folder ID %q in configuration", folder.ID) return fmt.Errorf("folder %q: %v", folder.ID, errFolderIDDuplicate)
} }
existingFolders[folder.ID] = folder existingFolders[folder.ID] = folder
} }

View File

@ -711,23 +711,19 @@ func TestDuplicateFolders(t *testing.T) {
// Duplicate folders are a loading error // Duplicate folders are a loading error
_, err := Load("testdata/dupfolders.xml", device1) _, err := Load("testdata/dupfolders.xml", device1)
if err == nil || !strings.HasPrefix(err.Error(), "duplicate folder ID") { if err == nil || !strings.Contains(err.Error(), errFolderIDDuplicate.Error()) {
t.Fatal(`Expected error to mention "duplicate folder ID":`, err) t.Fatal(`Expected error to mention "duplicate folder ID":`, err)
} }
} }
func TestEmptyFolderPaths(t *testing.T) { func TestEmptyFolderPaths(t *testing.T) {
// Empty folder paths are allowed at the loading stage, and should not // Empty folder paths are not allowed at the loading stage, and should not
// get messed up by the prepare steps (e.g., become the current dir or // get messed up by the prepare steps (e.g., become the current dir or
// get a slash added so that it becomes the root directory or similar). // get a slash added so that it becomes the root directory or similar).
wrapper, err := Load("testdata/nopath.xml", device1) _, err := Load("testdata/nopath.xml", device1)
if err != nil { if err == nil || !strings.Contains(err.Error(), errFolderPathEmpty.Error()) {
t.Fatal(err) t.Fatal("Expected error due to empty folder path, got", err)
}
folder := wrapper.Folders()["f1"]
if folder.cachedFilesystem != nil {
t.Errorf("Expected %q to be empty", folder.cachedFilesystem)
} }
} }
@ -929,6 +925,7 @@ func TestIssue4219(t *testing.T) {
"folders": [ "folders": [
{ {
"id": "abcd123", "id": "abcd123",
"path": "testdata",
"devices":[ "devices":[
{"deviceID": "GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY"} {"deviceID": "GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY"}
] ]

View File

@ -92,7 +92,7 @@ func (f FolderConfiguration) Copy() FolderConfiguration {
func (f FolderConfiguration) Filesystem() fs.Filesystem { func (f FolderConfiguration) Filesystem() fs.Filesystem {
// This is intentionally not a pointer method, because things like // This is intentionally not a pointer method, because things like
// cfg.Folders["default"].Filesystem() should be valid. // cfg.Folders["default"].Filesystem() should be valid.
if f.cachedFilesystem == nil && f.Path != "" { if f.cachedFilesystem == nil {
l.Infoln("bug: uncached filesystem call (should only happen in tests)") l.Infoln("bug: uncached filesystem call (should only happen in tests)")
return fs.NewFilesystem(f.FilesystemType, f.Path) return fs.NewFilesystem(f.FilesystemType, f.Path)
} }
@ -209,9 +209,7 @@ func (f *FolderConfiguration) DeviceIDs() []protocol.DeviceID {
} }
func (f *FolderConfiguration) prepare() { func (f *FolderConfiguration) prepare() {
if f.Path != "" { f.cachedFilesystem = fs.NewFilesystem(f.FilesystemType, f.Path)
f.cachedFilesystem = fs.NewFilesystem(f.FilesystemType, f.Path)
}
if f.RescanIntervalS > MaxRescanIntervalS { if f.RescanIntervalS > MaxRescanIntervalS {
f.RescanIntervalS = MaxRescanIntervalS f.RescanIntervalS = MaxRescanIntervalS

View File

@ -15,7 +15,7 @@
<!-- duplicate, will be removed --> <!-- duplicate, will be removed -->
<address>192.0.2.5</address> <address>192.0.2.5</address>
</device> </device>
<folder id="f2" directory="testdata/"> <folder id="f2" path="testdata/">
<device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device> <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
<device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA"></device> <device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA"></device>
<!-- duplicate device, will be removed --> <!-- duplicate device, will be removed -->

View File

@ -1,6 +1,6 @@
<configuration version="15"> <configuration version="15">
<folder id="f1" directory="testdata/"> <folder id="f1" path="testdata/">
</folder> </folder>
<folder id="f1" directory="testdata/"> <folder id="f1" path="testdata/">
</folder> </folder>
</configuration> </configuration>

View File

@ -8,7 +8,7 @@
<ignoredFolder id="folder1"/> <ignoredFolder id="folder1"/>
<ignoredFolder id="folder2"/> <ignoredFolder id="folder2"/>
</device> </device>
<folder id="folder1" directory="testdata/"> <folder id="folder1" path="testdata/">
<device id="GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY"></device> <device id="GYRZZQB-IRNPV4Z-T7TC52W-EQYJ3TT-FDQW6MW-DFLMU42-SSSU6EM-FBK2VAY"></device>
</folder> </folder>
</configuration> </configuration>

View File

@ -1,25 +1,25 @@
<configuration version="10"> <configuration version="10">
<folder id="f1" directory="testdata/"> <folder id="f1" path="testdata/">
</folder> </folder>
<folder id="f2" directory="testdata/"> <folder id="f2" path="testdata/">
<order>random</order> <order>random</order>
</folder> </folder>
<folder id="f3" directory="testdata/"> <folder id="f3" path="testdata/">
<order>alphabetic</order> <order>alphabetic</order>
</folder> </folder>
<folder id="f4" directory="testdata/"> <folder id="f4" path="testdata/">
<order>whatever</order> <order>whatever</order>
</folder> </folder>
<folder id="f5" directory="testdata/"> <folder id="f5" path="testdata/">
<order>smallestFirst</order> <order>smallestFirst</order>
</folder> </folder>
<folder id="f6" directory="testdata/"> <folder id="f6" path="testdata/">
<order>largestFirst</order> <order>largestFirst</order>
</folder> </folder>
<folder id="f7" directory="testdata/"> <folder id="f7" path="testdata/">
<order>oldestFirst</order> <order>oldestFirst</order>
</folder> </folder>
<folder id="f8" directory="testdata/"> <folder id="f8" path="testdata/">
<order>newestFirst</order> <order>newestFirst</order>
</folder> </folder>
</configuration> </configuration>