Skip to content

DeflateBuffer: skip header sniff on empty chunks#12995

Draft
HrachShah wants to merge 2 commits into
aio-libs:masterfrom
HrachShah:fix/deflate-buffer-empty-chunk
Draft

DeflateBuffer: skip header sniff on empty chunks#12995
HrachShah wants to merge 2 commits into
aio-libs:masterfrom
HrachShah:fix/deflate-buffer-empty-chunk

Conversation

@HrachShah

Copy link
Copy Markdown

What do these changes do?

DeflateBuffer.feed_data raised IndexError: string index out of range from the RFC1950 header sniff whenever the underlying transport resumed a paused decoder with feed_data(b""). The sniff is only meaningful when the first byte of the chunk actually arrived, so an empty chunk must be a no-op.

The guard now reads if (chunk and not self._started_decoding and self.encoding == "deflate" and chunk[0] & 0xF != 8): instead of if (not self._started_decoding and self.encoding == "deflate" and chunk[0] & 0xF != 8):. With chunk short-circuiting to False on b"", the branch is skipped before chunk[0] is read. The downstream decompress_sync(b"") already handles the empty payload correctly (the new test test_feed_empty_chunk_after_real_data covers this).

Are there changes in behavior for the user?

Yes — bugfix. A response that previously crashed with IndexError now decodes normally. No public API change.

Is it a substantial burden for the maintainers to support this?

No. The change is local to a single private class, has two new regression tests, and a CHANGES fragment. No new public API, no new dependencies, no new defaults.

Related issue number

Fixes #12994

Checklist

  • I think the code is well written
  • Unit tests for the changes exist
  • Documentation reflects the changes (CHANGES/12994.bugfix.rst added)
  • If you provide code modification, please add yourself to CONTRIBUTORS.txt
  • Add a new news fragment into the CHANGES/ folder
Test log
$ PYTHONPATH=/home/workspace/yarl:/home/workspace/aiohttp AIOHTTP_NO_EXTENSIONS=1 python3 -m pytest tests/test_http_parser.py::TestDeflateBuffer -v
...
======================== 12 passed, 1 skipped in 0.74s =========================

test_feed_empty_chunk_before_any_data fails on master with IndexError: index out of range from aiohttp/http_parser.py:1142 and passes with this fix. test_feed_empty_chunk_after_real_data passes both ways (regression-of-regression: the pre-existing decompress_sync(b"") path is left alone).

Drafted with Zo Computer (MiniMax M3); reviewed by HrachShah.

The deflate decoder FSM in feed_data() inspected chunk[0] to detect
a raw deflate stream (no zlib header) before any data had been seen.
AIOHTTP pauses and resumes decoders by calling feed_data(b""), and
on the first such resume the empty chunk made chunk[0] raise
IndexError, propagating out through the protocol's resume path.

Guard the sniff with an explicit empty-chunk check so feed_data(b"")
is a no-op before the decoder has started, while keeping the existing
behaviour for real first-byte data. Add two regression tests in
TestDeflateBuffer covering the empty-chunk-before-data and
empty-chunk-after-data cases.
@psf-chronographer psf-chronographer Bot added the bot:chronographer:provided There is a change note present in this PR label Jun 26, 2026
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.96%. Comparing base (85a150c) to head (40a3845).
⚠️ Report is 9 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #12995   +/-   ##
=======================================
  Coverage   98.95%   98.96%           
=======================================
  Files         131      131           
  Lines       48029    48103   +74     
  Branches     2495     2496    +1     
=======================================
+ Hits        47529    47603   +74     
  Misses        376      376           
  Partials      124      124           
Flag Coverage Δ
Autobahn 22.23% <21.05%> (-0.04%) ⬇️
CI-GHA 98.90% <100.00%> (-0.01%) ⬇️
OS-Linux 98.66% <100.00%> (-0.01%) ⬇️
OS-Windows 97.04% <100.00%> (+<0.01%) ⬆️
OS-macOS 97.94% <100.00%> (-0.01%) ⬇️
Py-3.10 98.14% <100.00%> (+<0.01%) ⬆️
Py-3.11 98.41% <100.00%> (+<0.01%) ⬆️
Py-3.12 98.50% <100.00%> (+<0.01%) ⬆️
Py-3.13 98.47% <100.00%> (+<0.01%) ⬆️
Py-3.14 98.49% <100.00%> (+<0.01%) ⬆️
Py-3.14t 97.58% <100.00%> (-0.01%) ⬇️
Py-pypy-3.11 97.44% <57.89%> (+<0.01%) ⬆️
VM-macos 97.94% <100.00%> (-0.01%) ⬇️
VM-ubuntu 98.66% <100.00%> (-0.01%) ⬇️
VM-windows 97.04% <100.00%> (+<0.01%) ⬆️
cython-coverage 38.04% <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 Harness.
📢 Have feedback on the report? Share it here.

@codspeed-hq

codspeed-hq Bot commented Jun 26, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 83 untouched benchmarks
⏩ 83 skipped benchmarks1


Comparing HrachShah:fix/deflate-buffer-empty-chunk (40a3845) with master (7987bd2)

Open in CodSpeed

Footnotes

  1. 83 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

DeflateBuffer.feed_data raises IndexError on empty chunks

1 participant