Skip to content

Commit 889dba9

Browse files
committed
PR icsharpcode#554 skip CRC calculation for AES zip entries
1 parent 9f9536b commit 889dba9

File tree

3 files changed

+45
-24
lines changed

3 files changed

+45
-24
lines changed

src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs

+20-9
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,8 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl
949949

950950
if (testing && testData && this[entryIndex].IsFile)
951951
{
952+
var checkCRC = this[entryIndex].AESKeySize == 0;
953+
952954
if (resultHandler != null)
953955
{
954956
status.SetOperation(TestOperation.EntryData);
@@ -964,7 +966,8 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl
964966
int bytesRead;
965967
while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0)
966968
{
967-
crc.Update(new ArraySegment<byte>(buffer, 0, bytesRead));
969+
if (checkCRC)
970+
crc.Update(new ArraySegment<byte>(buffer, 0, bytesRead));
968971

969972
if (resultHandler != null)
970973
{
@@ -975,13 +978,16 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl
975978
}
976979
}
977980

978-
if (this[entryIndex].Crc != crc.Value)
981+
if (checkCRC)
979982
{
980-
status.AddError();
983+
if (this[entryIndex].Crc != crc.Value)
984+
{
985+
status.AddError();
981986

982-
resultHandler?.Invoke(status, "CRC mismatch");
987+
resultHandler?.Invoke(status, "CRC mismatch");
983988

984-
testing &= strategy != TestStrategy.FindFirstError;
989+
testing &= strategy != TestStrategy.FindFirstError;
990+
}
985991
}
986992

987993
if ((this[entryIndex].Flags & (int)GeneralBitFlags.Descriptor) != 0)
@@ -991,10 +997,13 @@ public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandl
991997

992998
helper.ReadDataDescriptor(this[entryIndex].LocalHeaderRequiresZip64, data);
993999

994-
if (this[entryIndex].Crc != data.Crc)
1000+
if (checkCRC)
9951001
{
996-
status.AddError();
997-
resultHandler?.Invoke(status, "Descriptor CRC mismatch");
1002+
if (this[entryIndex].Crc != data.Crc)
1003+
{
1004+
status.AddError();
1005+
resultHandler?.Invoke(status, "Descriptor CRC mismatch");
1006+
}
9981007
}
9991008

10001009
if (this[entryIndex].CompressedSize != data.CompressedSize)
@@ -2633,6 +2642,8 @@ private void AddEntry(ZipFile workFile, ZipUpdate update)
26332642
source = updateDataSource_.GetSource(update.Entry, update.Filename);
26342643
}
26352644

2645+
var useCrc = update.Entry.AESKeySize == 0;
2646+
26362647
if (source != null)
26372648
{
26382649
using (source)
@@ -2653,7 +2664,7 @@ private void AddEntry(ZipFile workFile, ZipUpdate update)
26532664

26542665
using (Stream output = workFile.GetOutputStream(update.OutEntry))
26552666
{
2656-
CopyBytes(update, output, source, sourceStreamLength, true);
2667+
CopyBytes(update, output, source, sourceStreamLength, useCrc);
26572668
}
26582669

26592670
long dataEnd = workFile.baseStream_.Position;

src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ public int WriteDataDescriptor(ZipEntry entry)
450450
if ((entry.Flags & (int)GeneralBitFlags.Descriptor) != 0)
451451
{
452452
// The signature is not PKZIP originally but is now described as optional
453-
// in the PKZIP Appnote documenting trhe format.
453+
// in the PKZIP Appnote documenting the format.
454454
WriteLEInt(ZipConstants.DataDescriptorSignature);
455455
WriteLEInt(unchecked((int)(entry.Crc)));
456456

@@ -484,7 +484,7 @@ public void ReadDataDescriptor(bool zip64, DescriptorData data)
484484
int intValue = ReadLEInt();
485485

486486
// In theory this may not be a descriptor according to PKZIP appnote.
487-
// In practise its always there.
487+
// In practice its always there.
488488
if (intValue != ZipConstants.DataDescriptorSignature)
489489
{
490490
throw new ZipException("Data descriptor signature not found");

src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs

+23-13
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,9 @@ public void PutNextEntry(ZipEntry entry)
496496
/// <summary>
497497
/// Closes the current entry, updating header and footer information as required
498498
/// </summary>
499+
/// <exception cref="ZipException">
500+
/// Invalid entry field values.
501+
/// </exception>
499502
/// <exception cref="System.IO.IOException">
500503
/// An I/O error occurs.
501504
/// </exception>
@@ -526,7 +529,7 @@ public void CloseEntry()
526529
}
527530
else if (curMethod == CompressionMethod.Stored)
528531
{
529-
// This is done by Finsh() for Deflated entries, but we need to do it
532+
// This is done by Finish() for Deflated entries, but we need to do it
530533
// ourselves for Stored ones
531534
GetAuthCodeIfAES();
532535
}
@@ -535,6 +538,19 @@ public void CloseEntry()
535538
if (curEntry.AESKeySize > 0)
536539
{
537540
baseOutputStream_.Write(AESAuthCode, 0, 10);
541+
// Always use 0 as CRC for AE-2 format
542+
curEntry.Crc = 0;
543+
}
544+
else
545+
{
546+
if (curEntry.Crc < 0)
547+
{
548+
curEntry.Crc = crc.Value;
549+
}
550+
else if (curEntry.Crc != crc.Value)
551+
{
552+
throw new ZipException($"crc was {crc.Value}, but {curEntry.Crc} was expected");
553+
}
538554
}
539555

540556
if (curEntry.Size < 0)
@@ -543,7 +559,7 @@ public void CloseEntry()
543559
}
544560
else if (curEntry.Size != size)
545561
{
546-
throw new ZipException("size was " + size + ", but I expected " + curEntry.Size);
562+
throw new ZipException($"size was {size}, but {curEntry.Size} was expected");
547563
}
548564

549565
if (curEntry.CompressedSize < 0)
@@ -552,16 +568,7 @@ public void CloseEntry()
552568
}
553569
else if (curEntry.CompressedSize != csize)
554570
{
555-
throw new ZipException("compressed size was " + csize + ", but I expected " + curEntry.CompressedSize);
556-
}
557-
558-
if (curEntry.Crc < 0)
559-
{
560-
curEntry.Crc = crc.Value;
561-
}
562-
else if (curEntry.Crc != crc.Value)
563-
{
564-
throw new ZipException("crc was " + crc.Value + ", but I expected " + curEntry.Crc);
571+
throw new ZipException($"compressed size was {csize}, but {curEntry.CompressedSize} expected");
565572
}
566573

567574
offset += csize;
@@ -709,7 +716,10 @@ public override void Write(byte[] buffer, int offset, int count)
709716
throw new ArgumentException("Invalid offset/count combination");
710717
}
711718

712-
crc.Update(new ArraySegment<byte>(buffer, offset, count));
719+
// Only update CRC if AES is not enabled
720+
if (curEntry.AESKeySize == 0)
721+
crc.Update(new ArraySegment<byte>(buffer, offset, count));
722+
713723
size += count;
714724

715725
switch (curMethod)

0 commit comments

Comments
 (0)