diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs
index ec63d7943..4ecc86189 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFormat.cs
@@ -1,8 +1,8 @@
+using ICSharpCode.SharpZipLib.Core;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
-using ICSharpCode.SharpZipLib.Core;
namespace ICSharpCode.SharpZipLib.Zip
{
@@ -47,7 +47,7 @@ internal static class ZipFormat
{
// Write the local file header
// TODO: ZipFormat.WriteLocalHeader is not yet used and needs checking for ZipFile and ZipOuptutStream usage
- internal static int WriteLocalHeader(Stream stream, ZipEntry entry, out EntryPatchData patchData,
+ internal static int WriteLocalHeader(Stream stream, ZipEntry entry, out EntryPatchData patchData,
bool headerInfoAvailable, bool patchEntryHeader, long streamOffset, StringCodec stringCodec)
{
patchData = new EntryPatchData();
@@ -76,7 +76,7 @@ internal static int WriteLocalHeader(Stream stream, ZipEntry entry, out EntryPat
{
if (patchEntryHeader)
patchData.CrcPatchOffset = streamOffset + stream.Position;
-
+
stream.WriteLEInt(0); // Crc
if (patchEntryHeader)
@@ -178,21 +178,28 @@ internal static long LocateBlockWithSignature(Stream stream, int signature, long
long giveUpMarker = Math.Max(pos - maximumVariableData, 0);
- // TODO: This loop could be optimized for speed.
+ // cache part of stream which should be searched for signature
+ byte[] cache = new byte[(int)(pos - giveUpMarker) + 4];
+ stream.Seek(giveUpMarker, SeekOrigin.Begin);
+ stream.Read(cache, 0, cache.Length);
+ MemoryStream cacheStream = new MemoryStream(cache);
+
do
{
if (pos < giveUpMarker)
{
return -1;
}
- stream.Seek(pos--, SeekOrigin.Begin);
- } while (stream.ReadLEInt() != signature);
+ cacheStream.Seek(pos - giveUpMarker, SeekOrigin.Begin);
+ pos--;
+ } while (cacheStream.ReadLEInt() != signature);
+ stream.Seek(pos + 5, SeekOrigin.Begin);
return stream.Position;
}
///
- public static async Task WriteZip64EndOfCentralDirectoryAsync(Stream stream, long noOfEntries,
+ public static async Task WriteZip64EndOfCentralDirectoryAsync(Stream stream, long noOfEntries,
long sizeEntries, long centralDirOffset, CancellationToken cancellationToken)
{
await stream.WriteProcToStreamAsync(s => WriteZip64EndOfCentralDirectory(s, noOfEntries, sizeEntries, centralDirOffset), cancellationToken).ConfigureAwait(false);
@@ -234,11 +241,11 @@ internal static void WriteZip64EndOfCentralDirectory(Stream stream, long noOfEnt
}
///
- public static async Task WriteEndOfCentralDirectoryAsync(Stream stream, long noOfEntries, long sizeEntries,
- long start, byte[] comment, CancellationToken cancellationToken)
- => await stream.WriteProcToStreamAsync(s
+ public static async Task WriteEndOfCentralDirectoryAsync(Stream stream, long noOfEntries, long sizeEntries,
+ long start, byte[] comment, CancellationToken cancellationToken)
+ => await stream.WriteProcToStreamAsync(s
=> WriteEndOfCentralDirectory(s, noOfEntries, sizeEntries, start, comment), cancellationToken).ConfigureAwait(false);
-
+
///
/// Write the required records to end the central directory.
///
@@ -251,8 +258,8 @@ public static async Task WriteEndOfCentralDirectoryAsync(Stream stream, long no
internal static void WriteEndOfCentralDirectory(Stream stream, long noOfEntries, long sizeEntries, long start, byte[] comment)
{
if (noOfEntries >= 0xffff ||
- start >= 0xffffffff ||
- sizeEntries >= 0xffffffff)
+ start >= 0xffffffff ||
+ sizeEntries >= 0xffffffff)
{
WriteZip64EndOfCentralDirectory(stream, noOfEntries, sizeEntries, start);
}
@@ -459,7 +466,7 @@ internal static int WriteEndEntry(Stream stream, ZipEntry entry, StringCodec str
byte[] extra = ed.GetEntryData();
byte[] entryComment = !(entry.Comment is null)
- ? stringCodec.ZipOutputEncoding.GetBytes(entry.Comment)
+ ? stringCodec.ZipOutputEncoding.GetBytes(entry.Comment)
: Empty.Array();
if (entryComment.Length > 0xffff)
@@ -533,11 +540,11 @@ internal static void AddExtraDataAES(ZipEntry entry, ZipExtraData extraData)
extraData.AddNewEntry(0x9901);
}
- internal static async Task PatchLocalHeaderAsync(Stream stream, ZipEntry entry,
+ internal static async Task PatchLocalHeaderAsync(Stream stream, ZipEntry entry,
EntryPatchData patchData, CancellationToken ct)
{
var initialPos = stream.Position;
-
+
// Update CRC
stream.Seek(patchData.CrcPatchOffset, SeekOrigin.Begin);
await stream.WriteLEIntAsync((int)entry.Crc, ct).ConfigureAwait(false);
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs
index 0cf7395cb..f52deebb9 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipEncryptionHandling.cs
@@ -1,9 +1,9 @@
-using ICSharpCode.SharpZipLib.Zip;
+using ICSharpCode.SharpZipLib.Tests.TestSupport;
+using ICSharpCode.SharpZipLib.Zip;
using NUnit.Framework;
using System;
using System.IO;
using System.Text;
-using ICSharpCode.SharpZipLib.Tests.TestSupport;
using System.Threading.Tasks;
using Does = ICSharpCode.SharpZipLib.Tests.TestSupport.Does;
@@ -117,7 +117,7 @@ public void ZipFileAesRead()
{
var password = "password";
- using (var ms = new SingleByteReadingStream())
+ using (var ms = new MemoryStream() /* SingleByteReadingStream */)
{
WriteEncryptedZipToStream(ms, password, 256);
ms.Seek(0, SeekOrigin.Begin);
@@ -537,7 +537,7 @@ public void WriteEncryptedZipToStream(Stream stream, int entryCount, string pass
zs.SetLevel(9); // 0-9, 9 being the highest level of compression
zs.Password = password; // optional. Null is the same as not setting. Required if using AES.
- for (int i = 0; i < entryCount; i++)
+ for (int i = 0; i < entryCount; i++)
{
AddEncrypedEntryToStream(zs, $"test-{i}", keySize, compressionMethod);
}