From 9d799f40e1d4c0daec468b7dc6d1ab00ad698301 Mon Sep 17 00:00:00 2001 From: Anlo2846 <22388152+Anlo2846@users.noreply.github.com> Date: Sat, 4 Nov 2023 22:33:54 +0100 Subject: [PATCH 1/2] Added failing test, reading a zip archive embedded in a binary file. Ionic.Zip.ZipException HResult=0x80131500 Message=Cannot read that as a ZipFile Source=DotNetZip StackTrace: at Ionic.Zip.ZipFile.ReadIntoInstance(ZipFile zf) in DotNetZip.Semverd\src\Zip.Shared\ZipFile.Read.cs:line 660 at Ionic.Zip.ZipFile.Read(Stream zipStream, TextWriter statusMessageWriter, Encoding encoding, EventHandler`1 readProgress) in DotNetZip.Semverd\src\Zip.Shared\ZipFile.Read.cs:line 543 at Ionic.Zip.ZipFile.Read(Stream zipStream) in DotNetZip.Semverd\src\Zip.Shared\ZipFile.Read.cs:line 414 at Ionic.Zip.Tests.Streams.StreamsTests.ReadZip_WithOffset() in DotNetZip.Semverd\src\Zip Tests\Streams.cs:line 225 This exception was originally thrown at this call stack: Ionic.Zip.ZipFile.ReadCentralDirectoryFooter(Ionic.Zip.ZipFile) in ZipFile.Read.cs Ionic.Zip.ZipFile.ReadCentralDirectory(Ionic.Zip.ZipFile) in ZipFile.Read.cs Ionic.Zip.ZipFile.ReadIntoInstance(Ionic.Zip.ZipFile) in ZipFile.Read.cs Inner Exception 1: BadReadException: Bad signature (0000002C) at position 0x00000082 --- src/Zip Tests/Streams.cs | 23 +++++++++++++++++++++++ src/Zip Tests/Zip Tests.csproj | 3 +++ src/Zip Tests/zips/offset.bin | Bin 0 -> 136 bytes 3 files changed, 26 insertions(+) create mode 100644 src/Zip Tests/zips/offset.bin diff --git a/src/Zip Tests/Streams.cs b/src/Zip Tests/Streams.cs index a4993ae..ba67847 100644 --- a/src/Zip Tests/Streams.cs +++ b/src/Zip Tests/Streams.cs @@ -210,6 +210,29 @@ public void ReadZip_OpenReader() } + // Read a file consisting of a 16 byte header and one embedded zip archive + [TestMethod] + public void ReadZip_WithOffset() + { + string filename = Path.Combine(CurrentDir, "zips\\offset.bin"); + string header = null; + int entries = 0; + + using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (BinaryReader br = new BinaryReader(fs)) + { + header = Encoding.ASCII.GetString(br.ReadBytes(16)); + using (ZipFile zip = ZipFile.Read(fs)) + { + entries = zip.Entries.Count; + } + } + + Assert.AreEqual("16-byte header\0\0", header, "Error reading header"); + Assert.AreEqual(1, entries, "Error reading embedded zip file"); + } + + [TestMethod] public void ZOS_Create_WithComment_wi10339() { diff --git a/src/Zip Tests/Zip Tests.csproj b/src/Zip Tests/Zip Tests.csproj index 8c7be4b..5386b2c 100644 --- a/src/Zip Tests/Zip Tests.csproj +++ b/src/Zip Tests/Zip Tests.csproj @@ -165,6 +165,9 @@ Always + + Always + diff --git a/src/Zip Tests/zips/offset.bin b/src/Zip Tests/zips/offset.bin new file mode 100644 index 0000000000000000000000000000000000000000..d9fa011b1275ad4d96e225af8d5721bb26b086e5 GIT binary patch literal 136 zcmXps(@m-@Nma;5O-xBGVqggHW@Zs#00H$iDd7Qju`AhtY!K!E;*iwh61|d&5=SRz qLnGq=Z$>5&2HdKF8W Date: Sat, 4 Nov 2023 22:34:45 +0100 Subject: [PATCH 2/2] _originalPosition should only be added to offset when origin == Begin. --- src/Zip.Shared/OffsetStream.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Zip.Shared/OffsetStream.cs b/src/Zip.Shared/OffsetStream.cs index 525019a..a846274 100644 --- a/src/Zip.Shared/OffsetStream.cs +++ b/src/Zip.Shared/OffsetStream.cs @@ -90,7 +90,18 @@ public override long Position public override long Seek(long offset, System.IO.SeekOrigin origin) { - return _innerStream.Seek(_originalPosition + offset, origin) - _originalPosition; + switch (origin) + { + case SeekOrigin.Begin: + return _innerStream.Seek(_originalPosition + offset, origin) - _originalPosition; + + case SeekOrigin.Current: + case SeekOrigin.End: + return _innerStream.Seek(offset, origin) - _originalPosition; + + default: + throw new ArgumentOutOfRangeException(nameof(origin), origin, "Invalid seek origin"); + } }