Skip to content

Commit

Permalink
Throw exception on Store+Descriptor entries
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel committed Oct 3, 2020
1 parent 61d3a21 commit 2fb4a0b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
19 changes: 18 additions & 1 deletion src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
Expand Up @@ -493,6 +493,14 @@ private int ReadingNotSupported(byte[] destination, int offset, int count)
throw new ZipException("The compression method for this entry is not supported");
}

/// <summary>
/// Handle attempts to read from this entry by throwing an exception
/// </summary>
private int StoredDescriptorEntry(byte[] destination, int offset, int count) =>
throw new StreamUnsupportedException(
"The combination of Stored compression method and Descriptor flag is not possible to read using ZipInputStream");


/// <summary>
/// Perform the initial read on an entry which may include
/// reading encryption headers and setting up inflation.
Expand Down Expand Up @@ -544,13 +552,22 @@ private int InitialRead(byte[] destination, int offset, int count)
inputBuffer.CryptoTransform = null;
}

if ((csize > 0) || ((flags & (int)GeneralBitFlags.Descriptor) != 0))
var usesDescriptor = (flags & (int) GeneralBitFlags.Descriptor) != 0;

if ((csize > 0) || usesDescriptor)
{
if ((method == CompressionMethod.Deflated) && (inputBuffer.Available > 0))
{
inputBuffer.SetInflaterInput(inf);
}

// It's not possible to know how many bytes to read when using "Stored" compression (unless using encryption)
if (!entry.IsCrypted && method == CompressionMethod.Stored && usesDescriptor)
{
internalReader = StoredDescriptorEntry;
return StoredDescriptorEntry(destination, offset, count);
}

internalReader = new ReadDataHandler(BodyRead);
return BodyRead(destination, offset, count);
}
Expand Down
36 changes: 36 additions & 0 deletions test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
Expand Up @@ -502,5 +502,41 @@ public void ShouldBeAbleToReadEntriesWithInvalidFileNames()
}
}
}

[Test]
[Category("Zip")]
public void ShouldThrowDescriptiveExceptionOnUncompressedDescriptorEntry()
{
using (var ms = new MemoryStreamWithoutSeek())
{
using (var zos = new ZipOutputStream(ms))
{
zos.IsStreamOwner = false;
var entry = new ZipEntry("testentry");
entry.CompressionMethod = CompressionMethod.Stored;
entry.Flags |= (int)GeneralBitFlags.Descriptor;
zos.PutNextEntry(entry);
zos.Write(new byte[1], 0, 1);
zos.CloseEntry();
}

// Patch the Compression Method, since ZipOutputStream automatically changes it to Deflate when descriptors are used
ms.Seek(8, SeekOrigin.Begin);
ms.WriteByte((byte)CompressionMethod.Stored);
ms.Seek(0, SeekOrigin.Begin);

using (var zis = new ZipInputStream(ms))
{
zis.IsStreamOwner = false;
var buf = new byte[32];
zis.GetNextEntry();

Assert.Throws(typeof(StreamUnsupportedException), () =>
{
zis.Read(buf, 0, buf.Length);
});
}
}
}
}
}

0 comments on commit 2fb4a0b

Please sign in to comment.