From dc0734d97350e298ea73515238686d3b292e3c28 Mon Sep 17 00:00:00 2001 From: Andrew Nesbitt Date: Sat, 2 May 2026 15:30:27 +0100 Subject: [PATCH] Cap remote changelog body at 1 MiB in FetchAndParse --- fetch.go | 3 ++- fetch_test.go | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/fetch.go b/fetch.go index b84903e..d01cbcd 100644 --- a/fetch.go +++ b/fetch.go @@ -65,7 +65,8 @@ func FetchAndParse(ctx context.Context, repoURL, filename string) (*Parser, erro return nil, fmt.Errorf("HTTP %d fetching %s", resp.StatusCode, rawURL) } - body, err := io.ReadAll(resp.Body) + const maxBodySize = 1 << 20 + body, err := io.ReadAll(io.LimitReader(resp.Body, maxBodySize)) if err != nil { return nil, err } diff --git a/fetch_test.go b/fetch_test.go index b6cf186..94ef08a 100644 --- a/fetch_test.go +++ b/fetch_test.go @@ -4,6 +4,8 @@ import ( "context" "net/http" "net/http/httptest" + "net/url" + "strings" "testing" ) @@ -98,3 +100,38 @@ func TestFetchAndParse(t *testing.T) { } }) } + +type roundTripFunc func(*http.Request) (*http.Response, error) + +func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) { + return f(req) +} + +func TestFetchAndParseLimitsBodySize(t *testing.T) { + const limit = 1 << 20 + + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = w.Write([]byte("## [1.0.0] - 2024-01-01\n\n")) + _, _ = w.Write([]byte(strings.Repeat("a", limit*2))) + })) + defer srv.Close() + + srvURL, _ := url.Parse(srv.URL) + + origTransport := http.DefaultClient.Transport + http.DefaultClient.Transport = roundTripFunc(func(req *http.Request) (*http.Response, error) { + req.URL.Scheme = srvURL.Scheme + req.URL.Host = srvURL.Host + return http.DefaultTransport.RoundTrip(req) + }) + defer func() { http.DefaultClient.Transport = origTransport }() + + parser, err := FetchAndParse(context.Background(), "https://github.com/owner/repo", "CHANGELOG.md") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if len(parser.content) > limit { + t.Errorf("body not capped: got %d bytes, want <= %d", len(parser.content), limit) + } +}