[PR #1104] [MERGED] Fix InvalidOperationException when RAR uncompressed size exceeds header value #1534

Open
opened 2026-01-29 22:21:01 +00:00 by claunia · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/adamhathcock/sharpcompress/pull/1104
Author: @Copilot
Created: 1/4/2026
Status: Merged
Merged: 1/4/2026
Merged by: @adamhathcock

Base: masterHead: copilot/fix-invalidoperationexception-rar


📝 Commits (6)

  • bb66100 Initial plan
  • b25493f Fix InvalidOperationException when RAR unpacks more data than header specifies
  • 83b1125 Add test for InvalidOperationException fix in RAR extraction
  • 1257479 Update test to document exception behavior for RAR stream validation
  • 90a33ce Remove duplicate test that doesn't verify exception case
  • 41ed4c8 Add negative test case for premature stream termination

📊 Changes

3 files changed (+142 additions, -2 deletions)

View changed files

📝 src/SharpCompress/Compressors/Rar/RarStream.cs (+2 -2)
tests/SharpCompress.Test/Mocks/TruncatedStream.cs (+65 -0)
📝 tests/SharpCompress.Test/Rar/RarArchiveTests.cs (+75 -0)

📄 Description

  • Analyze the RarStream.cs validation logic
  • Identify the root cause of InvalidOperationException
  • Fix the validation condition in Read() method (line 137)
  • Fix the validation condition in ReadImplAsync() method (line 182)
  • Test the fix with existing RAR test files (283 tests passed)
  • Run all tests to verify no regressions (909 tests passed)
  • Run code review (no issues found)
  • Run security checks (no vulnerabilities found)
  • Add positive test for the InvalidOperationException fix (284 RAR tests pass)
  • Remove duplicate test per PR review feedback
  • Add negative test case that verifies exception is thrown on truncated streams (285 RAR tests pass)

Changes Made

Core Fix:

  • Modified validation in RarStream.Read() and RarStream.ReadImplAsync() from _position != Length to _position < Length
  • Exception now only thrown when decompression ends prematurely (genuine error), not when actual size exceeds header size (valid for some RAR files)

Test Coverage:

  • Positive test (Rar_StreamValidation_OnlyThrowsOnPrematureEnd): Validates normal extraction succeeds across RAR, RAR5, RAR4, and RAR2 formats without throwing when position >= expected length
  • Negative test (Rar_StreamValidation_ThrowsOnTruncatedStream): Verifies InvalidOperationException IS thrown when a RAR stream ends prematurely (position < expected length)
  • Mock class (TruncatedStream): Created to simulate corrupted/truncated RAR files for negative testing

This allows successful extraction of RAR archives where headers underestimate the uncompressed size, while still catching truncated/corrupted extractions.

<issue_title>InvalidOperationException when extracting RAR - 0.42.0, 0.42.1, 0.43.0</issue_title>
><issue_description>Extracting RAR files now raise InvalidOperationException
>
> Message:
> System.InvalidOperationException : unpacked file size does not match header: expected 22369776 found 31148016
>
> Stack Trace:
> RarStream.ReadImplAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
> RarStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
> Stream.</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
>
><comment_new>@adamhathcock
> I assume this worked with versions earlier than 0.42.0?
>
> What OS and can you give me a sample file?</comment_new>
>

Original prompt

This section details on the original issue you should resolve

<issue_title>InvalidOperationException when extracting RAR - 0.42.0, 0.42.1, 0.43.0</issue_title>
<issue_description>Extracting RAR files now raise InvalidOperationException

Message:
System.InvalidOperationException : unpacked file size does not match header: expected 22369776 found 31148016

Stack Trace:
RarStream.ReadImplAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
RarStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken)
Stream.g__Core|27_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)</issue_description>

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

@adamhathcock I assume this worked with versions earlier than 0.42.0?

What OS and can you give me a sample file?</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/adamhathcock/sharpcompress/pull/1104 **Author:** [@Copilot](https://github.com/apps/copilot-swe-agent) **Created:** 1/4/2026 **Status:** ✅ Merged **Merged:** 1/4/2026 **Merged by:** [@adamhathcock](https://github.com/adamhathcock) **Base:** `master` ← **Head:** `copilot/fix-invalidoperationexception-rar` --- ### 📝 Commits (6) - [`bb66100`](https://github.com/adamhathcock/sharpcompress/commit/bb66100486107342d157764253847cdcb75aed28) Initial plan - [`b25493f`](https://github.com/adamhathcock/sharpcompress/commit/b25493fd29dba37205b942ce4edfb41c8072db34) Fix InvalidOperationException when RAR unpacks more data than header specifies - [`83b1125`](https://github.com/adamhathcock/sharpcompress/commit/83b11254db4744171cded2d73d2206df5edbc042) Add test for InvalidOperationException fix in RAR extraction - [`1257479`](https://github.com/adamhathcock/sharpcompress/commit/12574798e18ca46a55438516c50432f8377a40da) Update test to document exception behavior for RAR stream validation - [`90a33ce`](https://github.com/adamhathcock/sharpcompress/commit/90a33ce6b063a177bd2bd0b3a1c856502c17d468) Remove duplicate test that doesn't verify exception case - [`41ed4c8`](https://github.com/adamhathcock/sharpcompress/commit/41ed4c81862c3f1e5676a37364b748b30ed4fa85) Add negative test case for premature stream termination ### 📊 Changes **3 files changed** (+142 additions, -2 deletions) <details> <summary>View changed files</summary> 📝 `src/SharpCompress/Compressors/Rar/RarStream.cs` (+2 -2) ➕ `tests/SharpCompress.Test/Mocks/TruncatedStream.cs` (+65 -0) 📝 `tests/SharpCompress.Test/Rar/RarArchiveTests.cs` (+75 -0) </details> ### 📄 Description - [x] Analyze the RarStream.cs validation logic - [x] Identify the root cause of InvalidOperationException - [x] Fix the validation condition in Read() method (line 137) - [x] Fix the validation condition in ReadImplAsync() method (line 182) - [x] Test the fix with existing RAR test files (283 tests passed) - [x] Run all tests to verify no regressions (909 tests passed) - [x] Run code review (no issues found) - [x] Run security checks (no vulnerabilities found) - [x] Add positive test for the InvalidOperationException fix (284 RAR tests pass) - [x] Remove duplicate test per PR review feedback - [x] Add negative test case that verifies exception is thrown on truncated streams (285 RAR tests pass) ## Changes Made **Core Fix:** - Modified validation in `RarStream.Read()` and `RarStream.ReadImplAsync()` from `_position != Length` to `_position < Length` - Exception now only thrown when decompression ends prematurely (genuine error), not when actual size exceeds header size (valid for some RAR files) **Test Coverage:** - **Positive test** (`Rar_StreamValidation_OnlyThrowsOnPrematureEnd`): Validates normal extraction succeeds across RAR, RAR5, RAR4, and RAR2 formats without throwing when position >= expected length - **Negative test** (`Rar_StreamValidation_ThrowsOnTruncatedStream`): Verifies `InvalidOperationException` IS thrown when a RAR stream ends prematurely (position < expected length) - **Mock class** (`TruncatedStream`): Created to simulate corrupted/truncated RAR files for negative testing This allows successful extraction of RAR archives where headers underestimate the uncompressed size, while still catching truncated/corrupted extractions. <issue_title>InvalidOperationException when extracting RAR - 0.42.0, 0.42.1, 0.43.0</issue_title> &gt;<issue_description>Extracting RAR files now raise InvalidOperationException &gt; &gt; **Message:** &gt; System.InvalidOperationException : unpacked file size does not match header: expected 22369776 found 31148016 &gt; &gt; **Stack Trace:** &gt; RarStream.ReadImplAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) &gt; RarStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken) &gt; Stream.</issue_description> &gt; &gt; ## Comments on the Issue (you are @copilot in this section) &gt; &gt;<comments> &gt;<comment_new><author>@adamhathcock</author> &gt; I assume this worked with versions earlier than 0.42.0? &gt; &gt; What OS and can you give me a sample file?</comment_new> &gt;</comments> <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>InvalidOperationException when extracting RAR - 0.42.0, 0.42.1, 0.43.0</issue_title> > <issue_description>Extracting RAR files now raise InvalidOperationException > > **Message:**  > System.InvalidOperationException : unpacked file size does not match header: expected 22369776 found 31148016 > > **Stack Trace:**  > RarStream.ReadImplAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) > RarStream.ReadAsync(Memory`1 buffer, CancellationToken cancellationToken) > Stream.<CopyToAsync>g__Core|27_0(Stream source, Stream destination, Int32 bufferSize, CancellationToken cancellationToken)</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@adamhathcock</author><body> > I assume this worked with versions earlier than 0.42.0? > > What OS and can you give me a sample file?</body></comment_new> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes adamhathcock/sharpcompress#1103 <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
claunia added the pull-request label 2026-01-29 22:21:01 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#1534