Skip to content

Fix SevenZipReader to maintain contiguous stream state for solid archives#1172

Merged
adamhathcock merged 6 commits intoreleasefrom
copilot/fix-sevenzip-contiguous-streams
Jan 28, 2026
Merged

Fix SevenZipReader to maintain contiguous stream state for solid archives#1172
adamhathcock merged 6 commits intoreleasefrom
copilot/fix-sevenzip-contiguous-streams

Conversation

Copy link
Contributor

Copilot AI commented Jan 27, 2026

SevenZipReader was recreating the decompression stream for each entry in solid archives (where multiple files share a compressed stream), breaking the sequential read requirement and causing data corruption and performance issues.

Changes

  • Maintain folder stream state: Added _currentFolderStream and _currentFolder fields to SevenZipReader
  • Create once, reuse: Decompression stream now created once per folder, shared across all entries in that folder
  • Sequential reads: Each entry reads sequentially from shared stream via ReadOnlySubStream bounded by entry size
  • Proper cleanup: Dispose folder stream when transitioning to new folder or on reader disposal

Implementation

protected override EntryStream GetEntryStream()
{
    var folder = _currentEntry.FilePart.Folder;
    
    // Create folder stream once, reuse for all entries in folder
    if (folder != _currentFolder)
    {
        _currentFolderStream?.Dispose();
        _currentFolderStream = _database.GetFolderStream(...);
        _currentFolder = folder;
    }
    
    // Read sequentially from shared stream
    return CreateEntryStream(
        new SyncOnlyStream(
            new ReadOnlySubStream(_currentFolderStream, entry.Size, leaveOpen: true)
        )
    );
}

Testing

  • Basic functionality test: SevenZipArchive_Solid_ExtractAllEntries_Contiguous verifies that solid archives can be extracted successfully using the reader
  • Stream reuse verification test: SevenZipArchive_Solid_VerifyStreamReuse uses reflection to access private fields and verify that:
    • The folder stream instance remains the same across all entries within a folder
    • The stream is never recreated within a folder (asserts streamRecreationsWithinFolder == 0)
    • Stream transitions only occur when moving to a different folder

This definitively proves the contiguous streaming behavior has been restored and that the stream is properly reused, not recreated per entry.

This restores the contiguous streaming behavior that existed before 0.41.0.

Original prompt

This section details on the original issue you should resolve

<issue_title>SevenZipReader (and maybe others) do not iterate entries as contiguous streams.</issue_title>
<issue_description>SevenZip (and SOLIID Rars) are one or more streams of compressed entries. Instead of Header then Compressed data, a single compressed stream has header then data inside it.

At some point after 0.41.0, this was broken for SevenZip. This needs to be fixed.

Use the parent issue (https://github.com/adamhathcock/sharpcompress/issue/1105) as information about the problem.

Tests should be made to ensure this situation doesn't happen again.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits January 27, 2026 17:01
Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix SevenZipReader to iterate entries as contiguous streams Fix SevenZipReader to maintain contiguous stream state for solid archives Jan 27, 2026
Copilot AI requested a review from adamhathcock January 27, 2026 17:15
@adamhathcock
Copy link
Owner

@copilot do more to test that it's the same contiguous stream. Should something be checked in the test to ensure it is for a solid stream or reader?

Co-authored-by: adamhathcock <527620+adamhathcock@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 27, 2026

@copilot do more to test that it's the same contiguous stream. Should something be checked in the test to ensure it is for a solid stream or reader?

Added a comprehensive test SevenZipArchive_Solid_VerifyStreamReuse that uses reflection to verify the folder stream is truly contiguous. The test:

  1. Accesses the private _currentFolderStream and _currentFolder fields via reflection
  2. Tracks folder transitions during extraction
  3. Verifies that within each folder, the stream instance is never recreated (stays the same object reference)
  4. Asserts streamRecreationsWithinFolder == 0 to ensure contiguous streaming

This definitively proves the stream is reused sequentially within each folder, not recreated per entry. Commit: 3c87242

@adamhathcock adamhathcock requested a review from Copilot January 28, 2026 08:15
@adamhathcock adamhathcock marked this pull request as ready for review January 28, 2026 08:15
@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Jan 28, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs - 0 issues
  • tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs - 0 issues

Copy link
Contributor

Copilot AI left a comment

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 restores contiguous streaming behavior for solid 7z archives by reusing a shared decoder stream per folder and adds targeted tests to prevent regressions.

Changes:

  • Refactors SevenZipArchive.SevenZipReader to maintain a shared _currentFolderStream per folder and expose internal diagnostics for testing.
  • Adjusts GetEntryStream to create a folder stream once and serve each entry via a bounded ReadOnlySubStream wrapped in SyncOnlyStream.
  • Adds solid-archive tests to verify contiguous extraction and to assert that the folder stream is reused rather than recreated, and updates test package locks to include Mono.Posix.NETStandard.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs Implements per-folder shared decoder stream, exposes diagnostics properties on SevenZipReader, and disposes the shared folder stream correctly on folder transitions and reader disposal.
tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs Adds regression tests for solid 7z contiguous extraction and for verifying that the internal folder stream is reused rather than recreated within a folder.
tests/SharpCompress.Test/packages.lock.json Adds Mono.Posix.NETStandard as a direct dependency for applicable test target frameworks.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
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.

3 participants