Skip to content

Fix server hang on chunked transfer encoding size mismatch#12119

Merged
Dreamsorcerer merged 3 commits intoaio-libs:masterfrom
worksbyfriday:fix-chunked-size-mismatch-10596
Feb 22, 2026
Merged

Fix server hang on chunked transfer encoding size mismatch#12119
Dreamsorcerer merged 3 commits intoaio-libs:masterfrom
worksbyfriday:fix-chunked-size-mismatch-10596

Conversation

@worksbyfriday
Copy link
Copy Markdown
Contributor

Summary

Fixes #10596.

When chunked transfer encoding chunk-size does not match the actual data length, the server hangs indefinitely instead of rejecting the request. Per RFC 9112, chunk-data must be exactly chunk-size octets followed by CRLF.

Root cause: In PARSE_CHUNKED_CHUNK_EOF state (after consuming chunk-size bytes), any data that doesn't start with \r\n is stored in _chunk_tail and the parser returns False — waiting forever for more data. When the chunk-size is wrong (e.g., declared 4 but sent 5 bytes), the byte after the consumed data is not \r and will never become \r\n.

Fix: Before falling through to the wait-for-more-data path, check whether the available data can't possibly be the start of the expected CRLF separator. If we have enough bytes to determine the separator is wrong, raise TransferEncodingError immediately. The legitimate partial-separator case (received \r but not yet \n) is preserved.

Changes:

  • aiohttp/http_parser.py: Add elif branch in PARSE_CHUNKED_CHUNK_EOF that raises TransferEncodingError when data doesn't match CRLF prefix
  • tests/test_http_parser.py: Two regression tests — data too long (5 bytes for chunk-size 4) and data too short (5 bytes for chunk-size 6)
  • CHANGES/10596.bugfix.rst: Changelog entry

Test plan

  • Two new tests pass: test_parse_chunked_payload_size_data_mismatch and test_parse_chunked_payload_size_data_mismatch_too_short
  • All 14 existing chunked payload tests pass (including split-end tests that verify partial CRLF handling)
  • Full test_http_parser.py suite: 299 passed, 4 pre-existing failures (missing C extension/brotli)

When chunk-size does not match actual data length, the server now raises
TransferEncodingError instead of hanging indefinitely. Per RFC 9112,
chunk-data must be exactly chunk-size octets followed by CRLF.

Previously, in PARSE_CHUNKED_CHUNK_EOF state, any data that didn't
start with CRLF was stored in _chunk_tail and the parser returned
False, waiting forever for more data that would never arrive.

The fix detects when we have enough bytes to determine the separator
is wrong (or the available bytes don't match the start of the expected
separator) and raises TransferEncodingError immediately.

Fixes aio-libs#10596.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@psf-chronographer psf-chronographer bot added the bot:chronographer:provided There is a change note present in this PR label Feb 22, 2026
@Dreamsorcerer Dreamsorcerer added backport-3.13 Trigger automatic backporting to the 3.13 release branch by Patchback robot backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot labels Feb 22, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.78%. Comparing base (4d15c33) to head (3baca13).
⚠️ Report is 2 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #12119      +/-   ##
==========================================
- Coverage   98.78%   98.78%   -0.01%     
==========================================
  Files         128      128              
  Lines       45279    45295      +16     
  Branches     2401     2402       +1     
==========================================
+ Hits        44730    44745      +15     
  Misses        390      390              
- Partials      159      160       +1     
Flag Coverage Δ
CI-GHA 98.64% <100.00%> (-0.01%) ⬇️
OS-Linux 98.38% <100.00%> (+<0.01%) ⬆️
OS-Windows 96.74% <100.00%> (-0.01%) ⬇️
OS-macOS 97.62% <100.00%> (-0.01%) ⬇️
Py-3.10.11 97.18% <100.00%> (-0.02%) ⬇️
Py-3.10.19 97.66% <100.00%> (+<0.01%) ⬆️
Py-3.11.14 97.86% <100.00%> (+<0.01%) ⬆️
Py-3.11.9 97.39% <100.00%> (+<0.01%) ⬆️
Py-3.12.10 97.48% <100.00%> (+<0.01%) ⬆️
Py-3.12.12 97.96% <100.00%> (+<0.01%) ⬆️
Py-3.13.11 97.95% <100.00%> (+<0.01%) ⬆️
Py-3.13.12 97.46% <100.00%> (+<0.01%) ⬆️
Py-3.14.2 97.91% <100.00%> (-0.02%) ⬇️
Py-3.14.3 97.41% <100.00%> (+<0.01%) ⬆️
Py-3.14.3t 97.26% <100.00%> (-0.01%) ⬇️
Py-pypy3.11.13-7.3.20 97.30% <100.00%> (+<0.01%) ⬆️
VM-macos 97.62% <100.00%> (-0.01%) ⬇️
VM-ubuntu 98.38% <100.00%> (+<0.01%) ⬆️
VM-windows 96.74% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Feb 22, 2026

Merging this PR will not alter performance

✅ 59 untouched benchmarks


Comparing Fridayai700:fix-chunked-size-mismatch-10596 (3baca13) with master (4d15c33)

Open in CodSpeed

@Dreamsorcerer Dreamsorcerer merged commit 0e2d3ec into aio-libs:master Feb 22, 2026
68 of 74 checks passed
@patchback
Copy link
Copy Markdown
Contributor

patchback bot commented Feb 22, 2026

Backport to 3.13: 💚 backport PR created

✅ Backport PR branch: patchback/backports/3.13/0e2d3ec48a950a2aacaf3f5d0d1f1597a1d5385b/pr-12119

Backported as #12121

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

patchback bot pushed a commit that referenced this pull request Feb 22, 2026
@patchback
Copy link
Copy Markdown
Contributor

patchback bot commented Feb 22, 2026

Backport to 3.14: 💚 backport PR created

✅ Backport PR branch: patchback/backports/3.14/0e2d3ec48a950a2aacaf3f5d0d1f1597a1d5385b/pr-12119

Backported as #12122

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

patchback bot pushed a commit that referenced this pull request Feb 22, 2026
Dreamsorcerer pushed a commit that referenced this pull request Feb 22, 2026
…er encoding size mismatch (#12122)

**This is a backport of PR #12119 as merged into master
(0e2d3ec).**

Co-authored-by: Fridayai700 <[email protected]>
Dreamsorcerer pushed a commit that referenced this pull request Feb 22, 2026
…er encoding size mismatch (#12121)

**This is a backport of PR #12119 as merged into master
(0e2d3ec).**

Co-authored-by: Fridayai700 <[email protected]>
wavebyrd pushed a commit to wavebyrd/aiohttp that referenced this pull request Mar 13, 2026
…d transfer encoding size mismatch (aio-libs#12121)

**This is a backport of PR aio-libs#12119 as merged into master
(cf2b944).**

Co-authored-by: Fridayai700 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-3.13 Trigger automatic backporting to the 3.13 release branch by Patchback robot backport-3.14 Trigger automatic backporting to the 3.14 release branch by Patchback robot bot:chronographer:provided There is a change note present in this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Server hangs when chunk-size does not match actual data size in chunked transfer encoding

2 participants