GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — `zlib._ZlibDecompressor(zdict=...)` raises `SystemError` on a zlib-wrapped stream · Issue #160001 · python/cpython

zlib._ZlibDecompressor(zdict=...) raises SystemError on a zlib-wrapped stream #160001

New issue
Copy link
New issue
Copy link
Open
Open
zlib._ZlibDecompressor(zdict=...) raises SystemError on a zlib-wrapped stream#160001
Copy link
Labels
extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@pganssle
pganssle
opened on Oct 21, 2026
Issue body actions

Bug description

zlib._ZlibDecompressor accepts a zdict argument, but for a zlib-wrapped stream (positive wbits) compressed with that dictionary, decompress fails with a SystemError instead of decompressing. zlib.decompressobj handles the same input:

>>> import zlib
>>> zd = b"hello world " * 10
>>> c = zlib.compressobj(zdict=zd)
>>> s = c.compress(b"hello world hello") + c.flush()
>>> zlib.decompressobj(zdict=zd).decompress(s)
b'hello world hello'
>>> zlib._ZlibDecompressor(zdict=zd).decompress(s)
Traceback (most recent call last):
  File "<python-input-5>", line 1, in <module>
    zlib._ZlibDecompressor(zdict=zd).decompress(s)
SystemError: <method 'decompress' of 'zlib._ZlibDecompressor' objects> returned NULL without setting an exception

Raw deflate works, so this is specific to the wrapped format:

>>> c = zlib.compressobj(wbits=-15, zdict=zd)
>>> s = c.compress(b"hello world hello") + c.flush()
>>> zlib._ZlibDecompressor(-15, zdict=zd).decompress(s)
b'hello world hello'

Two things combine here. The constructor only applies the dictionary up front for raw deflate (wbits < 0): Modules/zlibmodule.c lines 1775-1780. For a wrapped stream zlib instead signals Z_NEED_DICT after reading the header, and decompress_buf handles that by jumping to error without setting an exception: Modules/zlibmodule.c lines 1535-1541. zlib.Decompress handles the same return by calling inflateSetDictionary and continuing: Modules/zlibmodule.c lines 932-938, which is presumably what _ZlibDecompressor should do as well (and raise zlib.error when no zdict was given, as Decompress does).

_ZlibDecompressor is private and gzip only uses it with wbits=-15, so the impact is low; but a SystemError from a C method is always a bug, and the argument is accepted for this case, so we may as well fix it.

Found by the Hypothesis tests in #159960, recorded there as ZlibDecompressorZdictTests.test_zlib_wrapper under expectedFailure.

CPython versions tested on

CPython main (4e3d5ec), zlib 1.3.2

Operating systems tested on

Linux

Linked PRs

  • gh-160001: Honor the zdict of zlib._ZlibDecompressor on zlib-wrapped streams #161365

Activity

  1. pganssle
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Oct 21, 2026
  2. pganssle
    added a commit that references this issue on Oct 21, 2026

    Fix the known-bug tests on debug builds and zlib-ng

    e795310
  3. aisk
    added
    extension-modulesC modules in the Modules dirC modules in the Modules dir
    on Oct 21, 2026
  4. aisk
    added this to Compression issues 🗜on Oct 21, 2026
  5. pganssle
    added a commit that references this issue on Oct 21, 2026

    Keep FDICT zlib headers out of the invalid-input test and pin them

    bd9d844
  6. pganssle commented on Oct 21, 2026

    @pganssle
    pganssle
    on Oct 21, 2026
    MemberAuthor
    More actions

    Fuzzing the tests in #159960 under Atheris turned up a broader trigger for this: no zdict is needed. Any zlib-wrapped input whose header has the FDICT flag set makes _ZlibDecompressor.decompress return NULL without an exception, since that is exactly the Z_NEED_DICT branch linked above. Eight bytes are enough:

    >>> import zlib
    >>> stream = b"\x78\xbb" + b"\x00\x00\x00\x01\x03\x00"   # CMF/FLG with FDICT set
    >>> zlib.decompressobj().decompress(stream)
    Traceback (most recent call last):
      File "<python-input-2>", line 1, in <module>
        zlib.decompressobj().decompress(stream)
    zlib.error: Error 2 while decompressing data
    >>> zlib._ZlibDecompressor().decompress(stream)
    Traceback (most recent call last):
      File "<python-input-3>", line 1, in <module>
        zlib._ZlibDecompressor().decompress(stream)
    SystemError: <method 'decompress' of 'zlib._ZlibDecompressor' objects> returned NULL without setting an exception

    In a debug build that is a fatal C assertion in ceval.c rather than a SystemError, which is what killed the test worker on every CI job when #159960 first ran, so random invalid input reaches it easily. gzip only constructs _ZlibDecompressor with wbits=-15, where there is no header to carry the flag, so the stdlib's own use is not affected; it is only reachable by calling the private class with a positive or automatic wbits. So the "impact is low" assessment above still holds, but the fix should raise zlib.error for the no-zdict case rather than only wiring up inflateSetDictionary.

    #159960 now skips such headers in the zlib wrapper's test_invalid_input and pins the behaviour in test_fdict_header (release builds only, for the reason above).

  7. santhoshkumarselvaraj784-hue commented on Oct 22, 2026

    @santhoshkumarselvaraj784-hue
    santhoshkumarselvaraj784-hue
    on Oct 22, 2026
    More actions

    Hi, I’m a beginner Python developer and would like to make my first open-source contribution. I’m interested in working on this issue.

    Could you please let me know if I can work on it? I’ll follow the project’s contribution guidelines and submit a pull request once the changes are ready.
    @aisk

  8. aisk commented on Oct 22, 2026

    @aisk
    aisk
    on Oct 22, 2026
    Member
    More actions

    8. Hi, I’m a beginner Python developer and would like to make my first open-source contribution. I’m interested in working on this issue.
    Could you please let me know if I can work on it? I’ll follow the project’s contribution guidelines and submit a pull request once the changes are ready.
    @aisk

    Hi, we generally don't assign issues to people. If the issue is valid, the proposed fix makes sense, and nobody else is already working on it or has said they plan to, feel free to go ahead and open a PR. Please have a brief read of the devguide before starting.

  9. pganssle
    added 3 commits that reference this issue on Oct 23, 2026

    Fix the known-bug tests on debug builds and zlib-ng

    0442665

    Keep FDICT zlib headers out of the invalid-input test and pin them

    1c86a3e

    Pin the known compression bugs as expected-failure examples

    c197707
  10. compiler-segfault
    added a commit that references this issue on Nov 4, 2026

    pythongh-160001: Honor the zdict of zlib._ZlibDecompressor on wrapped…

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirC modules in the Modules dirtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    • Compression issues 🗜
      Status
      No status
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402520 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.