fix(protocol): handle zero-size requests (fixes #10709) (#10710)

- Allow zero-sized requests since they are sent by all current versions
of Syncthing.
- Stop sending zero-sized requests since that's stupid.

---------

Signed-off-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
Jakob Borg
2026-05-25 15:22:07 +02:00
committed by GitHub
parent 3ec73403c1
commit 6be1ff8480
4 changed files with 44 additions and 3 deletions
+1 -1
View File
@@ -483,7 +483,7 @@ func (c *rawConnection) dispatcherLoop() (err error) {
if err := checkFilename(msg.Name); err != nil {
return newProtocolError(err, msgContext)
}
if msg.Size <= 0 {
if msg.Size < 0 {
return newProtocolError(fmt.Errorf("request size %d too small", msg.Size), msgContext)
}
if msg.Size > MaxRequestSize {
+29 -1
View File
@@ -544,7 +544,7 @@ func TestDispatcherToCloseDeadlock(t *testing.T) {
}
func TestRequestMaxSize(t *testing.T) {
invalidSize := []int{-65536, 0, MaxRequestSize + 1}
invalidSize := []int{-65536, -1, MaxRequestSize + 1}
for _, s := range invalidSize {
t.Run(fmt.Sprintf("invalid/%d", s), func(t *testing.T) {
m := newTestModel()
@@ -592,6 +592,34 @@ func TestRequestMaxSize(t *testing.T) {
}
}
func TestRequestZeroSize(t *testing.T) {
// A zero-sized request should be accepted, since current versions of
// Syncthing send these. See https://github.com/syncthing/syncthing/issues/10709.
m := newTestModel()
rw := testutil.NewBlockingRW()
c := getRawConnection(NewConnection(c0ID, rw, &testutil.NoopRW{}, testutil.NoopCloser{}, m, new(mockedConnectionInfo), CompressionAlways, testKeyGen))
c.Start()
defer closeAndWait(c, rw)
c.inbox <- &bep.ClusterConfig{}
c.inbox <- &bep.Request{
Id: 1,
Name: "valid",
Size: 0,
}
select {
case res := <-c.outbox:
if msg, ok := res.msg.(*bep.Response); !ok || msg.Id != 1 {
t.Errorf("bad response %#v", msg)
}
case <-c.dispatcherLoopStopped:
t.Fatal("dispatcher loop terminated, expected zero-sized request to be accepted")
case <-time.After(time.Second):
t.Fatal("timed out waiting for response")
}
}
func TestRequestInvalidFilename(t *testing.T) {
m := newTestModel()
rw := testutil.NewBlockingRW()