From d36f46b1f2327eeb8cd5fb1ec5ce9f45346ecee2 Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Thu, 20 Aug 2026 10:26:17 -0600 Subject: [PATCH 1/2] Unconditionally consume buffers to avoid stale data --- src/brotlicffi/_api.py | 6 ++---- test/test_simple_decompression.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/brotlicffi/_api.py b/src/brotlicffi/_api.py index e6601f4..75a5182 100644 --- a/src/brotlicffi/_api.py +++ b/src/brotlicffi/_api.py @@ -497,10 +497,8 @@ def _decompress(self, data, output_buffer_limit): chunks.append(chunk) chunks_len += len(chunk) - # Save any unconsumed input for the next call. - if available_in[0] > 0: - remaining_input = ffi.buffer(next_in[0], available_in[0])[:] - self._unconsumed_data = remaining_input + # Save input for the next call + self._unconsumed_data = ffi.buffer(next_in[0], available_in[0])[:] # Check if we've reached the output limit. if ( diff --git a/test/test_simple_decompression.py b/test/test_simple_decompression.py index 232a730..dea8c96 100644 --- a/test/test_simple_decompression.py +++ b/test/test_simple_decompression.py @@ -89,6 +89,25 @@ def test_decompressobj_with_output_buffer_limit( assert final_result == uncompressed_data +def test_high_expansion_prefix_without_output_buffer_limit(): + """ + A fully-consumed mid-stream chunk must not leave stale unconsumed + input behind (issue #225). + """ + uncompressed = b''.join( + bytes([65 + (i % 26)]) * 4096 for i in range(16) + ) + compressed = brotlicffi.compress(uncompressed, lgwin=12) + assert len(compressed) > 64 + + o = brotlicffi.Decompressor() + result = o.decompress(compressed[:64]) + assert not o._unconsumed_data + assert o.can_accept_more_data() + result += o.decompress(compressed[64:]) + assert result == uncompressed + + def test_drip_feed(simple_compressed_file): """ Sending in the data one byte at a time still works. From 1b0be258ff6c41b785a9ec0ba5744eb099180b0e Mon Sep 17 00:00:00 2001 From: Nathan Goldbaum Date: Thu, 20 Aug 2026 10:29:09 -0600 Subject: [PATCH 2/2] Drop Python 3.8 builds --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 54d0380..412fbb3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,6 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] python-version: [ - ["3.8", "py38"], ["3.9", "py39"], ["3.10", "py310"], ["3.11", "py311"], @@ -96,7 +95,7 @@ jobs: - name: Build wheels run: python -m cibuildwheel --output-dir wheelhouse env: - CIBW_BUILD: "cp38-* pp*-* cp314t-*" + CIBW_BUILD: "cp39-* pp*-* cp314t-*" CIBW_SKIP: "*musllinux*" CIBW_ENABLE: pypy CIBW_ARCHS_LINUX: auto aarch64