diff --git a/gitea/client.go b/gitea/client.go index acd710c..bdc9a4a 100644 --- a/gitea/client.go +++ b/gitea/client.go @@ -11,6 +11,7 @@ import ( "fmt" "io" "log/slog" + "math" "net" "net/http" "net/url" @@ -69,7 +70,7 @@ type Client struct { RetryBackoff []time.Duration // MaxDiffSize is the maximum number of bytes allowed when fetching a PR diff. - // If zero, defaults to DefaultMaxDiffSize (10 MB). Set to -1 to disable the limit. + // If zero, defaults to DefaultMaxDiffSize (10 MB). Set to any negative value to disable the limit. MaxDiffSize int64 } @@ -442,7 +443,8 @@ func (c *Client) doGet(ctx context.Context, reqURL string) ([]byte, error) { // doGetLimited performs an HTTP GET request with retry (like doGet) but enforces // a maximum response body size. Returns ErrDiffTooLarge if the response exceeds -// maxBytes. It reads maxBytes+1 to detect overflow without buffering the entire body. +// maxBytes. It reads maxBytes+1 (clamped to avoid overflow) to detect truncation +// without buffering the entire body. func (c *Client) doGetLimited(ctx context.Context, reqURL string, maxBytes int64) ([]byte, error) { const maxAttempts = 3 backoff := c.RetryBackoff @@ -495,7 +497,12 @@ func (c *Client) doGetLimited(ctx context.Context, reqURL string, maxBytes int64 } if resp.StatusCode >= 200 && resp.StatusCode < 300 { // Read up to maxBytes+1 to detect overflow. - limited := io.LimitReader(resp.Body, maxBytes+1) + // Clamp to prevent integer overflow when maxBytes == math.MaxInt64. + limitBytes := maxBytes + 1 + if limitBytes <= 0 { + limitBytes = math.MaxInt64 + } + limited := io.LimitReader(resp.Body, limitBytes) body, err := io.ReadAll(limited) resp.Body.Close() if err != nil {