[PR #1015] Fix EndOfFileException crash in ZStandardStream.IsZStandard when reading streams with insufficient bytes #1440

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

Original Pull Request: https://github.com/adamhathcock/sharpcompress/pull/1015

State: closed
Merged: No


TarArchive.Open() crashes with EndOfFileException when processing TAR files or small streams. The crash occurs in ZStandardStream.IsZStandard() which attempts to read a UInt32 (4 bytes) without checking stream size.

Changes

  • ZStandardStream.IsZStandard(): Replace BinaryReader.ReadUInt32() with ReadBytes(4) and length validation before converting to UInt32, matching the pattern used by other compression format checks (BZip2Stream.IsBZip2(), GZipArchive.IsGZipFile())
  • TarArchiveTests: Add regression tests for empty and small streams

Before

internal static bool IsZStandard(Stream stream)
{
    var br = new BinaryReader(stream);
    var magic = br.ReadUInt32();  // Throws if stream has < 4 bytes
    if (ZstandardConstants.MAGIC != magic)
        return false;
    return true;
}

After

internal static bool IsZStandard(Stream stream)
{
    var br = new BinaryReader(stream);
    var bytes = br.ReadBytes(4);
    if (bytes.Length < 4)
        return false;
    var magic = BitConverter.ToUInt32(bytes, 0);
    if (ZstandardConstants.MAGIC != magic)
        return false;
    return true;
}
Original prompt

This section details on the original issue you should resolve

<issue_title>TarArchive.Open cause app crach</issue_title>
<issue_description>when I use code to compress a tar file :
var options = new ReaderOptions();
options.ArchiveEncoding.Default = Encoding.Default;
var archive = TarArchive.Open(ms, options);

it will crashed, and throw exception:

at System.ThrowHelper.ThrowEndOfFileException + 0x5(Unknown Source)
at System.IO.Stream.ReadAtLeastCore + 0x19(Unknown Source)
at System.IO.Stream.ReadExactly + 0x9(Unknown Source)
at System.IO.BinaryReader.InternalRead + 0x26(Unknown Source)
at System.IO.BinaryReader.ReadUInt32 + 0xb(Unknown Source)
at SharpCompress.Compressors.ZStandard.ZStandardStream.IsZStandard + 0x6(Unknown Source)
at SharpCompress.Readers.Tar.TarReader.Open + 0xae(Unknown Source)
at SharpCompress.Archives.Tar.TarArchive.CreateReaderForSolidExtraction + 0x18(Unknown Source)
at SharpCompress.Archives.AbstractArchive`2.ExtractAllEntries + 0x6(Unknown Source)
</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.

**Original Pull Request:** https://github.com/adamhathcock/sharpcompress/pull/1015 **State:** closed **Merged:** No --- `TarArchive.Open()` crashes with `EndOfFileException` when processing TAR files or small streams. The crash occurs in `ZStandardStream.IsZStandard()` which attempts to read a UInt32 (4 bytes) without checking stream size. ## Changes - **ZStandardStream.IsZStandard()**: Replace `BinaryReader.ReadUInt32()` with `ReadBytes(4)` and length validation before converting to UInt32, matching the pattern used by other compression format checks (`BZip2Stream.IsBZip2()`, `GZipArchive.IsGZipFile()`) - **TarArchiveTests**: Add regression tests for empty and small streams ## Before ```csharp internal static bool IsZStandard(Stream stream) { var br = new BinaryReader(stream); var magic = br.ReadUInt32(); // Throws if stream has < 4 bytes if (ZstandardConstants.MAGIC != magic) return false; return true; } ``` ## After ```csharp internal static bool IsZStandard(Stream stream) { var br = new BinaryReader(stream); var bytes = br.ReadBytes(4); if (bytes.Length < 4) return false; var magic = BitConverter.ToUInt32(bytes, 0); if (ZstandardConstants.MAGIC != magic) return false; return true; } ``` <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>TarArchive.Open cause app crach</issue_title> > <issue_description>when I use code to compress a tar file : > var options = new ReaderOptions(); > options.ArchiveEncoding.Default = Encoding.Default; > var archive = TarArchive.Open(ms, options); > > it will crashed, and throw exception: > > at System.ThrowHelper.ThrowEndOfFileException + 0x5(Unknown Source) > at System.IO.Stream.ReadAtLeastCore + 0x19(Unknown Source) > at System.IO.Stream.ReadExactly + 0x9(Unknown Source) > at System.IO.BinaryReader.InternalRead + 0x26(Unknown Source) > at System.IO.BinaryReader.ReadUInt32 + 0xb(Unknown Source) > at SharpCompress.Compressors.ZStandard.ZStandardStream.IsZStandard + 0x6(Unknown Source) > at SharpCompress.Readers.Tar.TarReader.Open + 0xae(Unknown Source) > at SharpCompress.Archives.Tar.TarArchive.CreateReaderForSolidExtraction + 0x18(Unknown Source) > at SharpCompress.Archives.AbstractArchive`2[[SharpCompress.Archives.Tar.TarArchiveEntry, SharpCompress, Version=0.41.0.0, Culture=neutral, PublicKeyToken=afb0a02973931d96],[SharpCompress.Common.Tar.TarVolume, SharpCompress, Version=0.41.0.0, Culture=neutral, PublicKeyToken=afb0a02973931d96]].ExtractAllEntries + 0x6(Unknown Source) > </issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> - Fixes adamhathcock/sharpcompress#1014 <!-- START COPILOT CODING AGENT TIPS --> --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
claunia added the pull-request label 2026-01-29 22:20:35 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/sharpcompress#1440