Skip to content

 Fix DeflateStream retaining stale buffer reference after write failure mid-operation - #132407

Open
alinpahontu2912 wants to merge 2 commits into
dotnet:mainfrom
alinpahontu2912:deflatestream_fix_dispose_write
Open

 Fix DeflateStream retaining stale buffer reference after write failure mid-operation#132407
alinpahontu2912 wants to merge 2 commits into
dotnet:mainfrom
alinpahontu2912:deflatestream_fix_dispose_write

Conversation

@alinpahontu2912

Copy link
Copy Markdown
Member

Fixes #132393

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @karelz, @dotnet/area-system-io-compression
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens System.IO.Compression’s deflate implementation against mid-operation failures by ensuring the zlib deflater/inflater won’t retain (and later read from) stale caller-provided input buffers after an exception propagates (e.g., write failure/cancellation), including during subsequent Dispose/flush paths.

Changes:

  • Add UnsetInput() helpers to Deflater and Inflater to discard any unconsumed input and release pinned references.
  • Ensure DeflateStream clears engine input on exceptions in deflate-output write loops and in CopyTo decompression forwarding.
  • Add regression tests intended to validate that stale input isn’t retained after failure paths.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs Adds UnsetInput() to drop unconsumed pinned input for inflate paths.
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs Clears stale input on exceptional paths during compress output writes and CopyTo decompression forwarding.
src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Deflater.cs Adds UnsetInput() to drop unconsumed pinned input for deflate paths.
src/libraries/Common/tests/System/IO/Compression/CompressionStreamUnitTestBase.cs Adds regression tests exercising exception mid-operation behavior for compression and decompression.

Comment thread src/libraries/Common/tests/System/IO/Compression/CompressionStreamUnitTestBase.cs Outdated

@iremyux iremyux left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The copilot comment looks legit, otherwise LGTM

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 19, 2026 08:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Suppressed comments (2)

src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/Inflater.cs:287

  • The XML doc comment has a grammatical typo: 'may since have' should be 'may have since' for correct wording.
        /// the inflater doesn't retain a dangling reference to a buffer the caller may since have reused or freed.

src/libraries/Common/tests/System/IO/Compression/CompressionStreamUnitTestBase.cs:172

  • This reflection lookup restricts to BindingFlags.Public, but NeedsInput on the internal engine types may be non-public. If so, GetMethod(...) returns null and the null-forgiving operator will cause a test failure. Use BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance (or otherwise handle a null MethodInfo) to make the test resilient to visibility.
            MethodInfo needsInputMethod = engine.GetType().GetMethod("NeedsInput", BindingFlags.Public | BindingFlags.Instance)!;
            return (bool)needsInputMethod.Invoke(engine, null)!;

/// Must be called if an in-progress operation is abandoned (e.g. due to an exception or cancellation) so
/// the deflater doesn't retain a dangling reference to a buffer the caller may since have reused or freed.
/// </summary>
internal void UnsetInput() => DeallocateInputBufferHandle(resetStreamHandle: true);
Copilot stopped reviewing on behalf of alinpahontu2912 due to an error August 19, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DeflateStream keeps reference to an input buffer and writes to it in Dispose

3 participants