Explorar o código

fix(protocol): slightly loosen/correct ownership comparison criteria (fixes #9879) (#10176)

Only Require either matching UID & GID OR matching Names.

If the 2 devices have a different Name => UID mapping, they can never be
totaly equal. Therefore when syncing we try matching the Name and fall
back to the UID. However when scanning for changes we currently require
both the Name & UID to match. This leads to forever having out of sync
files back and forth, or local additions when receive only.

This patch does not change the sending behavoir. It only change what we
decide is equal for exisiting files with mismapped Name => UID,

The added testcases show the change: Test 1,5,6 are the same as current.
Test 2,3 Are what change with this patch (from false to true). Test 4 is
a subset of test 2 they is currently special cased as true, which does
not chnage.

Co-authored-by: Jakob Borg <[email protected]>
yparitcher hai 4 meses
pai
achega
0b0b2143ed
Modificáronse 2 ficheiros con 43 adicións e 3 borrados
  1. 7 3
      lib/protocol/bep_fileinfo.go
  2. 36 0
      lib/protocol/bep_fileinfo_test.go

+ 7 - 3
lib/protocol/bep_fileinfo.go

@@ -858,9 +858,13 @@ func unixOwnershipEqual(a, b *UnixData) bool {
 	if a == nil || b == nil {
 		return false
 	}
-	ownerEqual := a.OwnerName == "" || b.OwnerName == "" || a.OwnerName == b.OwnerName
-	groupEqual := a.GroupName == "" || b.GroupName == "" || a.GroupName == b.GroupName
-	return a.UID == b.UID && a.GID == b.GID && ownerEqual && groupEqual
+	if a.UID == b.UID && a.GID == b.GID {
+		return true
+	}
+	if a.OwnerName == b.OwnerName && a.GroupName == b.GroupName {
+		return true
+	}
+	return false
 }
 
 func windowsOwnershipEqual(a, b *WindowsData) bool {

+ 36 - 0
lib/protocol/bep_fileinfo_test.go

@@ -196,6 +196,42 @@ func TestIsEquivalent(t *testing.T) {
 			b:  FileInfo{Type: FileInfoTypeFile, SymlinkTarget: []byte("b")},
 			eq: true,
 		},
+		// Unix Ownership should be the same
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			eq: true,
+		},
+		// ... but matching ID is enough
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "B", GroupName: "B", UID: 1000, GID: 1000}}},
+			eq: true,
+		},
+		// ... or matching name
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1001, GID: 1001}}},
+			eq: true,
+		},
+		// ... or empty name
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "", GroupName: "", UID: 1000, GID: 1000}}},
+			eq: true,
+		},
+		// ... but not different ownership
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "B", GroupName: "B", UID: 1001, GID: 1001}}},
+			eq: false,
+		},
+		// or missing ownership
+		{
+			a:  FileInfo{Platform: PlatformData{Unix: &UnixData{OwnerName: "A", GroupName: "A", UID: 1000, GID: 1000}}},
+			b:  FileInfo{Platform: PlatformData{}},
+			eq: false,
+		},
 	}
 
 	if build.IsWindows {