From 516f3e29e8cc7091ea6271715308caea0fcc0778 Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 11 Jan 2025 17:38:29 +0100 Subject: [PATCH] chore(proto): change symlinktarget to be byte sequence (fixes #9913) (#9914) --- internal/gen/bep/bep.pb.go | 8 ++++---- internal/gen/dbproto/structs.pb.go | 8 ++++---- lib/model/fakeconns_test.go | 2 +- lib/model/folder_sendrecv.go | 4 ++-- lib/model/folder_sendrecv_test.go | 4 ++-- lib/protocol/bep_fileinfo.go | 6 +++--- lib/protocol/bep_fileinfo_test.go | 8 ++++---- lib/scanner/walk.go | 2 +- lib/scanner/walk_test.go | 2 +- proto/bep/bep.proto | 2 +- proto/dbproto/structs.proto | 2 +- 11 files changed, 24 insertions(+), 24 deletions(-) diff --git a/internal/gen/bep/bep.pb.go b/internal/gen/bep/bep.pb.go index 7671339a4..686fc6c04 100644 --- a/internal/gen/bep/bep.pb.go +++ b/internal/gen/bep/bep.pb.go @@ -877,7 +877,7 @@ type FileInfo struct { Version *Vector `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"` Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"` Blocks []*BlockInfo `protobuf:"bytes,16,rep,name=blocks,proto3" json:"blocks,omitempty"` - SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"` + SymlinkTarget []byte `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"` BlocksHash []byte `protobuf:"bytes,18,opt,name=blocks_hash,json=blocksHash,proto3" json:"blocks_hash,omitempty"` Encrypted []byte `protobuf:"bytes,19,opt,name=encrypted,proto3" json:"encrypted,omitempty"` Type FileInfoType `protobuf:"varint,2,opt,name=type,proto3,enum=bep.FileInfoType" json:"type,omitempty"` @@ -983,11 +983,11 @@ func (x *FileInfo) GetBlocks() []*BlockInfo { return nil } -func (x *FileInfo) GetSymlinkTarget() string { +func (x *FileInfo) GetSymlinkTarget() []byte { if x != nil { return x.SymlinkTarget } - return "" + return nil } func (x *FileInfo) GetBlocksHash() []byte { @@ -2047,7 +2047,7 @@ var file_bep_bep_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x62, 0x65, 0x70, 0x2e, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x06, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x18, diff --git a/internal/gen/dbproto/structs.pb.go b/internal/gen/dbproto/structs.pb.go index 3a803347d..48f588b98 100644 --- a/internal/gen/dbproto/structs.pb.go +++ b/internal/gen/dbproto/structs.pb.go @@ -34,7 +34,7 @@ type FileInfoTruncated struct { ModifiedBy uint64 `protobuf:"varint,12,opt,name=modified_by,json=modifiedBy,proto3" json:"modified_by,omitempty"` Version *bep.Vector `protobuf:"bytes,9,opt,name=version,proto3" json:"version,omitempty"` Sequence int64 `protobuf:"varint,10,opt,name=sequence,proto3" json:"sequence,omitempty"` - SymlinkTarget string `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"` + SymlinkTarget []byte `protobuf:"bytes,17,opt,name=symlink_target,json=symlinkTarget,proto3" json:"symlink_target,omitempty"` BlocksHash []byte `protobuf:"bytes,18,opt,name=blocks_hash,json=blocksHash,proto3" json:"blocks_hash,omitempty"` Encrypted []byte `protobuf:"bytes,19,opt,name=encrypted,proto3" json:"encrypted,omitempty"` Type bep.FileInfoType `protobuf:"varint,2,opt,name=type,proto3,enum=bep.FileInfoType" json:"type,omitempty"` @@ -133,11 +133,11 @@ func (x *FileInfoTruncated) GetSequence() int64 { return 0 } -func (x *FileInfoTruncated) GetSymlinkTarget() string { +func (x *FileInfoTruncated) GetSymlinkTarget() []byte { if x != nil { return x.SymlinkTarget } - return "" + return nil } func (x *FileInfoTruncated) GetBlocksHash() []byte { @@ -760,7 +760,7 @@ var file_dbproto_structs_proto_rawDesc = []byte{ 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x74, 0x61, 0x72, - 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, + 0x67, 0x65, 0x74, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x79, 0x6d, 0x6c, 0x69, 0x6e, 0x6b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x63, diff --git a/lib/model/fakeconns_test.go b/lib/model/fakeconns_test.go index c51a87af4..0d929bb82 100644 --- a/lib/model/fakeconns_test.go +++ b/lib/model/fakeconns_test.go @@ -97,7 +97,7 @@ func (f *fakeConnection) addFileLocked(name string, flags uint32, ftype protocol file.Name = name file.Type = ftype file.Version = version - file.SymlinkTarget = string(data) + file.SymlinkTarget = data file.NoPermissions = true } f.files = append(f.files, file) diff --git a/lib/model/folder_sendrecv.go b/lib/model/folder_sendrecv.go index ceb74d130..73e3ef184 100644 --- a/lib/model/folder_sendrecv.go +++ b/lib/model/folder_sendrecv.go @@ -743,7 +743,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, snap *db.Snaps l.Debugf("need symlink\n\t%v\n\t%v", file, curFile) } - if file.SymlinkTarget == "" { + if len(file.SymlinkTarget) == 0 { // Index entry from a Syncthing predating the support for including // the link target in the index entry. We log this as an error. f.newPullError(file.Name, errIncompatibleSymlink) @@ -758,7 +758,7 @@ func (f *sendReceiveFolder) handleSymlink(file protocol.FileInfo, snap *db.Snaps // We declare a function that acts on only the path name, so // we can pass it to InWritableDir. createLink := func(path string) error { - if err := f.mtimefs.CreateSymlink(file.SymlinkTarget, path); err != nil { + if err := f.mtimefs.CreateSymlink(string(file.SymlinkTarget), path); err != nil { return err } return f.setPlatformData(&file, path) diff --git a/lib/model/folder_sendrecv_test.go b/lib/model/folder_sendrecv_test.go index c8e528208..69b35c018 100644 --- a/lib/model/folder_sendrecv_test.go +++ b/lib/model/folder_sendrecv_test.go @@ -891,7 +891,7 @@ func TestCopyOwner(t *testing.T) { Name: "foo/bar/sym", Type: protocol.FileInfoTypeSymlink, Permissions: 0o644, - SymlinkTarget: "over the rainbow", + SymlinkTarget: []byte("over the rainbow"), } f.handleSymlink(symlink, snap, dbUpdateChan, scanChan) @@ -958,7 +958,7 @@ func TestSRConflictReplaceFileByLink(t *testing.T) { // Simulate remote creating a symlink with the same name file.Type = protocol.FileInfoTypeSymlink - file.SymlinkTarget = "bar" + file.SymlinkTarget = []byte("bar") rem := device1.Short() file.Version = protocol.Vector{}.Update(rem) file.ModifiedBy = rem diff --git a/lib/protocol/bep_fileinfo.go b/lib/protocol/bep_fileinfo.go index d8ed11b5e..fa5f78d5d 100644 --- a/lib/protocol/bep_fileinfo.go +++ b/lib/protocol/bep_fileinfo.go @@ -66,7 +66,7 @@ type FileInfo struct { Version Vector Sequence int64 Blocks []BlockInfo - SymlinkTarget string + SymlinkTarget []byte BlocksHash []byte Encrypted []byte Platform PlatformData @@ -187,7 +187,7 @@ type FileInfoWithoutBlocks interface { GetVersion() *bep.Vector GetSequence() int64 // GetBlocks() []*bep.BlockInfo // not included - GetSymlinkTarget() string + GetSymlinkTarget() []byte GetBlocksHash() []byte GetEncrypted() []byte GetType() FileInfoType @@ -469,7 +469,7 @@ func (f FileInfo) isEquivalent(other FileInfo, comp FileInfoComparison) bool { case FileInfoTypeFile: return f.Size == other.Size && ModTimeEqual(f.ModTime(), other.ModTime(), comp.ModTimeWindow) && (comp.IgnoreBlocks || f.BlocksEqual(other)) case FileInfoTypeSymlink: - return f.SymlinkTarget == other.SymlinkTarget + return bytes.Equal(f.SymlinkTarget, other.SymlinkTarget) case FileInfoTypeDirectory: return true } diff --git a/lib/protocol/bep_fileinfo_test.go b/lib/protocol/bep_fileinfo_test.go index f3be6ba00..ec241db68 100644 --- a/lib/protocol/bep_fileinfo_test.go +++ b/lib/protocol/bep_fileinfo_test.go @@ -185,15 +185,15 @@ func TestIsEquivalent(t *testing.T) { // The symlink target is checked for symlinks { - a: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: "a"}, - b: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: "b"}, + a: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: []byte("a")}, + b: FileInfo{Type: FileInfoTypeSymlink, SymlinkTarget: []byte("b")}, eq: false, }, // ... but not for non-symlinks { - a: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: "a"}, - b: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: "b"}, + a: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: []byte("a")}, + b: FileInfo{Type: FileInfoTypeFile, SymlinkTarget: []byte("b")}, eq: true, }, } diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index d9d6f6e79..e76ce9651 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -740,7 +740,7 @@ func CreateFileInfo(fi fs.FileInfo, name string, filesystem fs.Filesystem, scanO if err != nil { return protocol.FileInfo{}, err } - f.SymlinkTarget = target + f.SymlinkTarget = []byte(target) f.NoPermissions = true // Symlinks don't have permissions of their own return f, nil } diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index c483484a0..5c6254d29 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -367,7 +367,7 @@ func TestWalkSymlinkUnix(t *testing.T) { if len(files[0].Blocks) != 0 { t.Errorf("expected zero blocks for symlink, not %d", len(files[0].Blocks)) } - if files[0].SymlinkTarget != "../testdata" { + if string(files[0].SymlinkTarget) != "../testdata" { t.Errorf("expected symlink to have target destination, not %q", files[0].SymlinkTarget) } } diff --git a/proto/bep/bep.proto b/proto/bep/bep.proto index c1dac02be..4cac50597 100644 --- a/proto/bep/bep.proto +++ b/proto/bep/bep.proto @@ -101,7 +101,7 @@ message FileInfo { Vector version = 9; int64 sequence = 10; repeated BlockInfo blocks = 16; - string symlink_target = 17; + bytes symlink_target = 17; bytes blocks_hash = 18; bytes encrypted = 19; FileInfoType type = 2; diff --git a/proto/dbproto/structs.proto b/proto/dbproto/structs.proto index bc49b4079..f8ff2eaa4 100644 --- a/proto/dbproto/structs.proto +++ b/proto/dbproto/structs.proto @@ -15,7 +15,7 @@ message FileInfoTruncated { bep.Vector version = 9; int64 sequence = 10; reserved 16; // blocks - string symlink_target = 17; + bytes symlink_target = 17; bytes blocks_hash = 18; bytes encrypted = 19; bep.FileInfoType type = 2;