From fa101f4f490dee2e4f5fbec726a55babacdc7e30 Mon Sep 17 00:00:00 2001 From: krau <71133316+krau@users.noreply.github.com> Date: Fri, 28 Aug 2026 00:04:23 +0800 Subject: [PATCH] fix(tdler): only apply EOF guard when size is known Photos pass size 0 (unknown, not available in InputPhotoFileLocation); the guard then answered the first request at offset 0 with an empty chunk, silently saving every photo as a 0-byte file. Fixes #238 --- common/tdler/dler.go | 2 +- common/tdler/dler_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/common/tdler/dler.go b/common/tdler/dler.go index 292ca2e..f965bce 100644 --- a/common/tdler/dler.go +++ b/common/tdler/dler.go @@ -28,7 +28,7 @@ type eofAwareClient struct { } func (c eofAwareClient) UploadGetFile(ctx context.Context, req *tg.UploadGetFileRequest) (tg.UploadFileClass, error) { - if req.Offset >= c.size { + if c.size > 0 && req.Offset >= c.size { return &tg.UploadFile{}, nil } return c.Client.UploadGetFile(ctx, req) diff --git a/common/tdler/dler_test.go b/common/tdler/dler_test.go index 0389782..44bff20 100644 --- a/common/tdler/dler_test.go +++ b/common/tdler/dler_test.go @@ -110,3 +110,31 @@ func TestDownloadServerLikeEOF(t *testing.T) { }) } } + +// Photos have no size in InputPhotoFileLocation, so TGFile.Size() is 0 +// ("unknown"). The EOF guard must not fire on the very first request at +// offset 0, or the download silently yields a 0-byte file. +func TestDownloadPhotoUnknownSize(t *testing.T) { + data := make([]byte, 89708) + for i := range data { + data[i] = byte(i % 251) + } + client := &serverLikeClient{data: data} + file := tfile.NewTGFile( + &tg.InputPhotoFileLocation{ID: 1, AccessHash: 2}, + client, 0, "photo.png", + ) + + dl := NewDownloader(file) + buf := make([]byte, len(data)) + _, err := dl.WithThreads(1).Parallel(context.Background(), &memWriterAt{b: buf}) + if err != nil { + t.Fatalf("download failed: %v", err) + } + if !bytes.Equal(buf, data) { + t.Fatalf("downloaded %d bytes, want %d matching bytes", len(buf), len(data)) + } + if client.maxOffset >= int64(len(data)) { + t.Fatalf("requested offset %d at or past EOF (size %d)", client.maxOffset, len(data)) + } +}