Skip to content

fix: accept request bodies of exactly MaxBodyBytes - #1131

Merged
robtme merged 2 commits into
danielgtaylor:mainfrom
APX403:fix/body-limit-boundary
Oct 15, 2026
Merged

robtme merged 2 commits into
danielgtaylor:mainfrom
APX403:fix/body-limit-boundary

Conversation

@APX403

@APX403 APX403 commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

readBody wraps the request body in io.LimitReader(reader, maxBytes) and treats count == maxBytes as an overflow, so a body whose size is exactly MaxBodyBytes is rejected with 413 even though it does not exceed the limit. The request limits documentation promises a 413 only for bodies larger than the limit, and the comment on Operation.MaxBodyBytes was the one place describing the inclusive behaviour. With the default of 1 MiB this is easy to hit: an upload sized to the advertised limit fails.

The fix reads one byte past the limit and rejects on count > maxBytes, so a body of exactly the limit passes while anything longer is still detected without buffering more than one extra byte. A limit of math.MaxInt64 is left alone so that the extra byte cannot overflow. The MaxBodyBytes comment now matches the documentation. This is a behaviour change for anyone who relied on the old rejection: an operation that used to refuse a body of exactly MaxBodyBytes now accepts it, and a limit that was set one byte high to work around this now accepts one more byte than intended.

Four cases join the table-driven TestFeatures suite next to the existing request-body-too-large case: a 12-byte JSON body against a 12-byte limit is accepted, the same body against an 11-byte limit gets 413, MaxBodyBytes: -1 accepts a body just over 2 MiB, and MaxBodyBytes: math.MaxInt64 is accepted as unlimited. go test -race ./... passes.

This is the off-by-one that robtme pointed out while reviewing #1095 (and noted again on #1094); it predates both pull requests, and the review there suggested a separate PR for it. #1094 applies the same inclusive check (r.N == 0) to multipart bodies, so if it lands first that check would need the same adjustment; this change only touches readBody.

APX403 and others added 2 commits October 12, 2026 08:34
readBody limited the reader to maxBytes and treated count == maxBytes as an overflow, so a body of exactly the configured limit was rejected with 413 although the request limits documentation promises that status only for larger bodies. Read one byte past the limit and reject on count > maxBytes, leave a limit of math.MaxInt64 unchanged so the extra byte cannot overflow, add table-driven cases for the exact size, one byte over, the -1 opt-out and the largest limit, and align the MaxBodyBytes comment with the documentation.
Stdlib already accepts exactly n bytes and handles MaxInt64 without
overflow, so the +1 read and the guard can go. A MaxBytesError from an
upstream reader (e.g. chi RequestSize) now returns 413 with its own limit
instead of 500.
@robtme

robtme commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

Thanks! I pushed a small follow-up that swaps the +1 read for http.MaxBytesReader, which already accepts exactly n bytes and handles MaxInt64, so the guard and its test could go. It also maps an upstream MaxBytesError (e.g. chi RequestSize) to 413 with that limit instead of 500.

@codecov

codecov Bot commented Oct 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.21%. Comparing base (5677656) to head (693e290).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1131      +/-   ##
==========================================
+ Coverage   93.19%   93.21%   +0.01%     
==========================================
  Files          24       24              
  Lines        5012     5011       -1     
==========================================
  Hits         4671     4671              
  Misses        273      273              
+ Partials       68       67       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@robtme
robtme merged commit 6c0666d into danielgtaylor:main Oct 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants