diff --git a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs index 8a6449c9..accae7d0 100644 --- a/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs +++ b/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs @@ -87,6 +87,15 @@ namespace SharpCompress.Common.Zip.Headers } ushort length = DataConverter.LittleEndian.GetUInt16(extra, i + 2); + + // 7zip has this same kind of check to ignore extras blocks that don't conform to the standard 2-byte ID, 2-byte length, N-byte value. + // CPP/7Zip/Zip/ZipIn.cpp: CInArchive::ReadExtra + if (length > extra.Length) + { + // bad extras block + return; + } + byte[] data = new byte[length]; Buffer.BlockCopy(extra, i + 4, data, 0, length); Extra.Add(LocalEntryHeaderExtraFactory.Create(type, length, data)); @@ -99,4 +108,4 @@ namespace SharpCompress.Common.Zip.Headers internal bool IsZip64 => CompressedSize == uint.MaxValue; } -} \ No newline at end of file +} diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs index 2576f253..f76b380d 100644 --- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs +++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs @@ -512,5 +512,29 @@ namespace SharpCompress.Test.Zip } } } + + [Fact] + public void Zip_BadLocalExtra_Read() + { + string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.badlocalextra.zip"); + + using (ZipArchive za = ZipArchive.Open(zipPath)) + { + var ex = Record.Exception(() => + { + var firstEntry = za.Entries.First(x => x.Key == "first.txt"); + var buffer = new byte[4096]; + + using (var memoryStream = new MemoryStream()) + using (var firstStream = firstEntry.OpenEntryStream()) + { + firstStream.CopyTo(memoryStream); + Assert.Equal(199, memoryStream.Length); + } + }); + + Assert.Null(ex); + } + } } } diff --git a/tests/TestArchives/Archives/Zip.badlocalextra.zip b/tests/TestArchives/Archives/Zip.badlocalextra.zip new file mode 100644 index 00000000..3a812a53 Binary files /dev/null and b/tests/TestArchives/Archives/Zip.badlocalextra.zip differ