Skip to content

Commit

Permalink
Merge pull request #686 from Erior/477
Browse files Browse the repository at this point in the history
Mitigation of problems
  • Loading branch information
adamhathcock authored Jul 29, 2022
2 parents c1110f2 + 5706732 commit 3f6027e
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 7 deletions.
32 changes: 29 additions & 3 deletions src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,38 @@ internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStr
{
_decompressionStream ??= GetCompressedStream();

_decompressionStream.Skip();
if( Header.CompressionMethod != ZipCompressionMethod.None )
{
_decompressionStream.Skip();

if (_decompressionStream is DeflateStream deflateStream)
if (_decompressionStream is DeflateStream deflateStream)
{
rewindableStream.Rewind(deflateStream.InputBuffer);
}
}
else
{
rewindableStream.Rewind(deflateStream.InputBuffer);
// We would need to search for the magic word
rewindableStream.Position -= 4;
var pos = rewindableStream.Position;
while( Utility.Find(rewindableStream, new byte[] { 0x50,0x4b,0x07,0x08 } ) )
{
// We should probably check CRC32 for positive matching as well
var size = rewindableStream.Position - pos;
var br = new BinaryReader(rewindableStream);
br.ReadUInt32();
br.ReadUInt32(); // CRC32
var compressed_size = br.ReadUInt32();
var uncompressed_size = br.ReadUInt32();
if (compressed_size == size && compressed_size == uncompressed_size )
{
rewindableStream.Position -= 16;
break;
}
rewindableStream.Position -= 12;
}
}

Skipped = true;
}
var reader = new BinaryReader(rewindableStream);
Expand Down
2 changes: 1 addition & 1 deletion src/SharpCompress/Readers/AbstractReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ private void SkipEntry()
private void Skip()
{
var part = Entry.Parts.First();
part.Skipped = true;

if (ArchiveType != ArchiveType.Rar
&& !Entry.IsSolid
Expand All @@ -145,6 +144,7 @@ private void Skip()
{
var bytesToAdvance = Entry.CompressedSize;
rawStream.Skip(bytesToAdvance);
part.Skipped = true;
return;
}
}
Expand Down
35 changes: 35 additions & 0 deletions src/SharpCompress/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,41 @@ public static void Skip(this Stream source)
}
}

public static bool Find(this Stream source, byte[] array)
{
byte[] buffer = GetTransferByteArray();
try
{
var pos = source.Position;
int count = 0;
var len = source.Read(buffer, 0, buffer.Length);
source.Position = pos + len;

do
{
for (int i = 0; i < len; i++)
{
if (array[count] == buffer[i])
{
count++;
if (count == array.Length)
{
source.Position = source.Position - len + i - array.Length +1;
return true;
}
}
}
}
while ((len = source.Read(buffer, 0, buffer.Length)) > 0);
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}

return false;
}

public static DateTime DosDateToDateTime(UInt16 iDate, UInt16 iTime)
{
int year = iDate / 512 + 1980;
Expand Down
11 changes: 9 additions & 2 deletions tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -738,13 +738,20 @@ public void Zip_Zip64_CompressedSizeExtraOnly_Read()
[Fact]
public void Zip_Uncompressed_Skip_All()
{
string zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip");
var keys = new string[] { "Folder/File1.txt", "Folder/File2.rtf", "Folder2/File1.txt", "Folder2/File2.txt", "DEADBEEF" };
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip");
using (var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read))
{
IArchive archive = ArchiveFactory.Open(stream);
IReader reader = archive.ExtractAllEntries();
int x = 0;
while (reader.MoveToNextEntry())
;
{
Assert.Equal(keys[x], reader.Entry.Key);
x++;
}

Assert.Equal(4, x);
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion tests/SharpCompress.Test/Zip/ZipReaderTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.IO;
Expand Down Expand Up @@ -368,5 +368,21 @@ public void Zip_None_Issue86_Streamed_Read()
}
}

[Fact]
public void Zip_ReaderMoveToNextEntry()
{
var keys = new string[] { "version", "sizehint", "data/0/metadata", "data/0/records" };

using (var fileStream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "test_477.zip")))
using (var reader = ZipReader.Open(fileStream))
{
foreach( var key in keys)
{
reader.MoveToNextEntry();

Assert.Equal(reader.Entry.Key, key);
}
}
}
}
}
Binary file added tests/TestArchives/Archives/test_477.zip
Binary file not shown.

0 comments on commit 3f6027e

Please sign in to comment.