From 99cb356b5ec17d9bc6b97b77ce5b17e6db33e93b Mon Sep 17 00:00:00 2001 From: Richard Webb Date: Tue, 12 May 2020 00:41:18 +0100 Subject: [PATCH] In ZipOutputStream.PutNextEntry, account for AES overhead when calculating compressed entry size --- src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs | 22 ++++++++++++++++++- .../Zip/ZipOutputStream.cs | 17 ++++++-------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs index a6241cb0f..803c8a4ca 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs @@ -655,7 +655,7 @@ public bool LocalHeaderRequiresZip64 if ((versionToExtract == 0) && IsCrypted) { - trueCompressedSize += ZipConstants.CryptoHeaderSize; + trueCompressedSize += (ulong)this.EncryptionOverheadSize; } // TODO: A better estimation of the true limit based on compression overhead should be used @@ -1013,6 +1013,26 @@ internal int AESOverheadSize } } + /// + /// Number of extra bytes required to hold the encryption header fields. + /// + internal int EncryptionOverheadSize + { + get + { + // Entry is not encrypted - no overhead + if (!this.IsCrypted) + return 0; + + // Entry is encrypted using ZipCrypto + if (_aesEncryptionStrength == 0) + return ZipConstants.CryptoHeaderSize; + + // Entry is encrypted using AES + return this.AESOverheadSize; + } + } + /// /// Process extra data fields updating the entry based on the contents. /// diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs index bfd308daa..e7f72f048 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs @@ -337,7 +337,9 @@ public void PutNextEntry(ZipEntry entry) } else { - WriteLeInt(entry.IsCrypted ? (int)entry.CompressedSize + ZipConstants.CryptoHeaderSize : (int)entry.CompressedSize); + int entryCompressedSize = (int)entry.CompressedSize + entry.EncryptionOverheadSize; + + WriteLeInt(entryCompressedSize); WriteLeInt((int)entry.Size); } } @@ -382,7 +384,9 @@ public void PutNextEntry(ZipEntry entry) if (headerInfoAvailable) { ed.AddLeLong(entry.Size); - ed.AddLeLong(entry.CompressedSize); + + long entryCompressedSize = entry.CompressedSize + entry.EncryptionOverheadSize; + ed.AddLeLong(entryCompressedSize); } else { @@ -540,14 +544,7 @@ public void CloseEntry() if (curEntry.IsCrypted) { - if (curEntry.AESKeySize > 0) - { - curEntry.CompressedSize += curEntry.AESOverheadSize; - } - else - { - curEntry.CompressedSize += ZipConstants.CryptoHeaderSize; - } + curEntry.CompressedSize += curEntry.EncryptionOverheadSize; } // Patch the header if possible