Skip to content

Commit

Permalink
Naive implementation of searching of DataDescriptor, not compatible w…
Browse files Browse the repository at this point in the history
…ith big archives (>32bit), but handles test cases.
  • Loading branch information
Erior committed Jul 28, 2022
1 parent ad633a9 commit 5706732
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
18 changes: 18 additions & 0 deletions src/SharpCompress/Common/Zip/StreamingZipFilePart.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,24 @@ internal BinaryReader FixStreamedFileLocation(ref RewindableStream rewindableStr
else
{
// 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;
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
4 changes: 1 addition & 3 deletions tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -751,9 +751,7 @@ public void Zip_Uncompressed_Skip_All()
x++;
}

// if we implement searching for DataDescriptor on none compressed streams
// this would work, see StreamingZipFilePart function FixStreamedFileLocation
// Assert.Equal(4, x);
Assert.Equal(4, x);
}
}
}
Expand Down

0 comments on commit 5706732

Please sign in to comment.