Browse Source

Merge pull request #2632 from calmh/fix2627

Ensure loaded config is free of duplicate devices (fixes #2627)
Audrius Butkevicius 10 years ago
parent
commit
1edfa4474f
3 changed files with 82 additions and 2 deletions
  1. 23 2
      lib/config/config.go
  2. 26 0
      lib/config/config_test.go
  3. 33 0
      lib/config/testdata/duplicates.xml

+ 23 - 2
lib/config/config.go

@@ -199,6 +199,9 @@ func (cfg *Configuration) prepare(myID protocol.DeviceID) {
 		existingDevices[myID] = true
 	}
 
+	// Ensure that the device list is free from duplicates
+	cfg.Devices = ensureNoDuplicateDevices(cfg.Devices)
+
 	sort.Sort(DeviceConfigurationList(cfg.Devices))
 	// Ensure that any loose devices are not present in the wrong places
 	// Ensure that there are no duplicate devices
@@ -206,7 +209,7 @@ func (cfg *Configuration) prepare(myID protocol.DeviceID) {
 	for i := range cfg.Folders {
 		cfg.Folders[i].Devices = ensureDevicePresent(cfg.Folders[i].Devices, myID)
 		cfg.Folders[i].Devices = ensureExistingDevices(cfg.Folders[i].Devices, existingDevices)
-		cfg.Folders[i].Devices = ensureNoDuplicates(cfg.Folders[i].Devices)
+		cfg.Folders[i].Devices = ensureNoDuplicateFolderDevices(cfg.Folders[i].Devices)
 		sort.Sort(FolderDeviceConfigurationList(cfg.Folders[i].Devices))
 	}
 
@@ -408,7 +411,25 @@ loop:
 	return devices[0:count]
 }
 
-func ensureNoDuplicates(devices []FolderDeviceConfiguration) []FolderDeviceConfiguration {
+func ensureNoDuplicateFolderDevices(devices []FolderDeviceConfiguration) []FolderDeviceConfiguration {
+	count := len(devices)
+	i := 0
+	seenDevices := make(map[protocol.DeviceID]bool)
+loop:
+	for i < count {
+		id := devices[i].DeviceID
+		if _, ok := seenDevices[id]; ok {
+			devices[i] = devices[count-1]
+			count--
+			continue loop
+		}
+		seenDevices[id] = true
+		i++
+	}
+	return devices[0:count]
+}
+
+func ensureNoDuplicateDevices(devices []DeviceConfiguration) []DeviceConfiguration {
 	count := len(devices)
 	i := 0
 	seenDevices := make(map[protocol.DeviceID]bool)

+ 26 - 0
lib/config/config_test.go

@@ -592,3 +592,29 @@ func TestGUIConfigURL(t *testing.T) {
 		}
 	}
 }
+
+func TestRemoveDuplicateDevicesFolders(t *testing.T) {
+	wrapper, err := Load("testdata/duplicates.xml", device1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// All folders are loaded, but the duplicate ones are disabled.
+	if l := len(wrapper.Raw().Folders); l != 3 {
+		t.Errorf("Incorrect number of folders, %d != 3", l)
+	}
+	for i, f := range wrapper.Raw().Folders {
+		if f.ID == "f1" && f.Invalid == "" {
+			t.Errorf("Folder %d (%q) is not set invalid", i, f.ID)
+		}
+	}
+
+	if l := len(wrapper.Raw().Devices); l != 3 {
+		t.Errorf("Incorrect number of devices, %d != 3", l)
+	}
+
+	f := wrapper.Folders()["f2"]
+	if l := len(f.Devices); l != 2 {
+		t.Errorf("Incorrect number of folder devices, %d != 2", l)
+	}
+}

+ 33 - 0
lib/config/testdata/duplicates.xml

@@ -0,0 +1,33 @@
+<configuration version="12">
+    <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR">
+        <address>192.0.2.1</address>
+        <address>192.0.2.2</address>
+    </device>
+    <device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA">
+        <address>192.0.2.3:6070</address>
+        <address>[2001:db8::42]:4242</address>
+    </device>
+    <device id="LGFPDIT7SKNNJVJZA4FC7QNCRKCE753K72BW5QD2FOZ7FRFEP57Q">
+        <address>[2001:db8::44]:4444</address>
+        <address>192.0.2.4:6090</address>
+    </device>
+    <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR">
+        <!-- duplicate, will be removed -->
+        <address>192.0.2.5</address>
+    </device>
+    <folder id="f1" directory="testdata/">
+        <!-- duplicate, will be disabled -->
+        <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
+        <device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA"></device>
+    </folder>
+    <folder id="f1" directory="testdata/">
+        <!-- duplicate, will be disabled -->
+        <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
+    </folder>
+    <folder id="f2" directory="testdata/">
+        <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
+        <device id="GYRZZQBIRNPV4T7TC52WEQYJ3TFDQW6MWDFLMU4SSSU6EMFBK2VA"></device>
+        <!-- duplicate device, will be removed -->
+        <device id="AIR6LPZ-7K4PTTV-UXQSMUU-CPQ5YWH-OEDFIIQ-JUG777G-2YQXXR5-YD6AWQR"></device>
+    </folder>
+</configuration>