Skip to content

Commit 2fb4a0b

Browse files
committed
Throw exception on Store+Descriptor entries
1 parent 61d3a21 commit 2fb4a0b

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs

+18-1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,14 @@ private int ReadingNotSupported(byte[] destination, int offset, int count)
493493
throw new ZipException("The compression method for this entry is not supported");
494494
}
495495

496+
/// <summary>
497+
/// Handle attempts to read from this entry by throwing an exception
498+
/// </summary>
499+
private int StoredDescriptorEntry(byte[] destination, int offset, int count) =>
500+
throw new StreamUnsupportedException(
501+
"The combination of Stored compression method and Descriptor flag is not possible to read using ZipInputStream");
502+
503+
496504
/// <summary>
497505
/// Perform the initial read on an entry which may include
498506
/// reading encryption headers and setting up inflation.
@@ -544,13 +552,22 @@ private int InitialRead(byte[] destination, int offset, int count)
544552
inputBuffer.CryptoTransform = null;
545553
}
546554

547-
if ((csize > 0) || ((flags & (int)GeneralBitFlags.Descriptor) != 0))
555+
var usesDescriptor = (flags & (int) GeneralBitFlags.Descriptor) != 0;
556+
557+
if ((csize > 0) || usesDescriptor)
548558
{
549559
if ((method == CompressionMethod.Deflated) && (inputBuffer.Available > 0))
550560
{
551561
inputBuffer.SetInflaterInput(inf);
552562
}
553563

564+
// It's not possible to know how many bytes to read when using "Stored" compression (unless using encryption)
565+
if (!entry.IsCrypted && method == CompressionMethod.Stored && usesDescriptor)
566+
{
567+
internalReader = StoredDescriptorEntry;
568+
return StoredDescriptorEntry(destination, offset, count);
569+
}
570+
554571
internalReader = new ReadDataHandler(BodyRead);
555572
return BodyRead(destination, offset, count);
556573
}

test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs

+36
Original file line numberDiff line numberDiff line change
@@ -502,5 +502,41 @@ public void ShouldBeAbleToReadEntriesWithInvalidFileNames()
502502
}
503503
}
504504
}
505+
506+
[Test]
507+
[Category("Zip")]
508+
public void ShouldThrowDescriptiveExceptionOnUncompressedDescriptorEntry()
509+
{
510+
using (var ms = new MemoryStreamWithoutSeek())
511+
{
512+
using (var zos = new ZipOutputStream(ms))
513+
{
514+
zos.IsStreamOwner = false;
515+
var entry = new ZipEntry("testentry");
516+
entry.CompressionMethod = CompressionMethod.Stored;
517+
entry.Flags |= (int)GeneralBitFlags.Descriptor;
518+
zos.PutNextEntry(entry);
519+
zos.Write(new byte[1], 0, 1);
520+
zos.CloseEntry();
521+
}
522+
523+
// Patch the Compression Method, since ZipOutputStream automatically changes it to Deflate when descriptors are used
524+
ms.Seek(8, SeekOrigin.Begin);
525+
ms.WriteByte((byte)CompressionMethod.Stored);
526+
ms.Seek(0, SeekOrigin.Begin);
527+
528+
using (var zis = new ZipInputStream(ms))
529+
{
530+
zis.IsStreamOwner = false;
531+
var buf = new byte[32];
532+
zis.GetNextEntry();
533+
534+
Assert.Throws(typeof(StreamUnsupportedException), () =>
535+
{
536+
zis.Read(buf, 0, buf.Length);
537+
});
538+
}
539+
}
540+
}
505541
}
506542
}

0 commit comments

Comments
 (0)