Skip to content

fix(zstream): fail on truncated input instead of looping forever - #7346

Open
weihanglo wants to merge 3 commits into
libgit2:mainfrom
weihanglo:zstream-infloop
Open

fix(zstream): fail on truncated input instead of looping forever#7346
weihanglo wants to merge 3 commits into
libgit2:mainfrom
weihanglo:zstream-infloop

Conversation

@weihanglo

@weihanglo weihanglo commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

What does this fix?

Fixes #7342.

inflate() reports Z_BUF_ERROR when a truncated stream exhausts its input before reaching Z_STREAM_END.

The stock zstream_seterr suggests treating that as non-fatal so callers can retry with more input or output space.

libgit2/deps/zlib/zlib.h

Lines 513 to 515 in d535450

buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
inflate() can be called again with more input and more output space to
continue decompressing. If Z_DATA_ERROR is returned, the application may

However, the drain loop in git_zstream_get_output can supply neither because

  • output space is still available
  • input is only refilled outside the loop

It would leads to zero-progress forever.

The problematic behavior was found in git_odb_read on a truncated loose object.

The proposed fix here: Detect the stuck state in the drain loop and report an error.

How to review

Commit by commit.

cb4c344 the odb test will loop forever if you drop the first fix commit.


🤖 LLM disclosure: This bug was found by LLM. Tests were generated by LLM. I've review carefully all the generated content and analysis.

`inflate()` reports `Z_BUF_ERROR` when a truncated stream exhausts
its input before reaching `Z_STREAM_END`.

The stock `zstream_seterr` suggests treating that as non-fatal
so callers can retry with more input or output space.

However,
the drain loop in `git_zstream_get_output` can supply neither because

* output space is still available
* input is only refilled outside the loop

It would leads to zero-progress forever.

The problematic behavior was found in `git_odb_read`
on a truncated loose object.

The proposed fix here:
Detect the stuck state in the drain loop and report an error.
When inflating a stream,
if the stream is truncated midway,
it must fail rather than loop forever.
This ensure that `git_odb_read` fails
when reading truncated loose object.

If you move this before the fix commit,
this loops forever
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.

zlib loops forever when reading a truncated loose objects

1 participant