diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs
index 2f326ab0e..c607cf9f2 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs
@@ -263,13 +263,7 @@ public ZipEntry(ZipEntry entry)
///
/// Get a value indicating whether the entry has a CRC value available.
///
- public bool HasCrc
- {
- get
- {
- return (known & Known.Crc) != 0;
- }
- }
+ public bool HasCrc => (known & Known.Crc) != 0;
///
/// Get/Set flag indicating if entry is encrypted.
@@ -278,21 +272,8 @@ public bool HasCrc
/// This is an assistant that interprets the flags property.
public bool IsCrypted
{
- get
- {
- return (flags & 1) != 0;
- }
- set
- {
- if (value)
- {
- flags |= 1;
- }
- else
- {
- flags &= ~1;
- }
- }
+ get => this.HasFlag(GeneralBitFlags.Encrypted);
+ set => this.SetFlag(GeneralBitFlags.Encrypted, value);
}
///
@@ -302,21 +283,8 @@ public bool IsCrypted
/// This is an assistant that interprets the flags property.
public bool IsUnicodeText
{
- get
- {
- return (flags & (int)GeneralBitFlags.UnicodeText) != 0;
- }
- set
- {
- if (value)
- {
- flags |= (int)GeneralBitFlags.UnicodeText;
- }
- else
- {
- flags &= ~(int)GeneralBitFlags.UnicodeText;
- }
- }
+ get => this.HasFlag(GeneralBitFlags.UnicodeText);
+ set => this.SetFlag(GeneralBitFlags.UnicodeText, value);
}
///
@@ -324,15 +292,8 @@ public bool IsUnicodeText
///
internal byte CryptoCheckValue
{
- get
- {
- return cryptoCheckValue_;
- }
-
- set
- {
- cryptoCheckValue_ = value;
- }
+ get => cryptoCheckValue_;
+ set => cryptoCheckValue_ = value;
}
///
@@ -368,14 +329,8 @@ internal byte CryptoCheckValue
///
public int Flags
{
- get
- {
- return flags;
- }
- set
- {
- flags = value;
- }
+ get => flags;
+ set => flags = value;
}
///
@@ -384,14 +339,8 @@ public int Flags
/// This is only valid when the entry is part of a
public long ZipFileIndex
{
- get
- {
- return zipFileIndex;
- }
- set
- {
- zipFileIndex = value;
- }
+ get => zipFileIndex;
+ set => zipFileIndex = value;
}
///
@@ -399,34 +348,18 @@ public long ZipFileIndex
///
public long Offset
{
- get
- {
- return offset;
- }
- set
- {
- offset = value;
- }
+ get => offset;
+ set => offset = value;
}
///
/// Get/Set external file attributes as an integer.
- /// The values of this are operating system dependant see
+ /// The values of this are operating system dependent see
/// HostSystem for details
///
public int ExternalFileAttributes
{
- get
- {
- if ((known & Known.ExternalAttributes) == 0)
- {
- return -1;
- }
- else
- {
- return externalFileAttributes;
- }
- }
+ get => (known & Known.ExternalAttributes) == 0 ? -1 : externalFileAttributes;
set
{
@@ -440,25 +373,14 @@ public int ExternalFileAttributes
/// The value / 10 indicates the major version number, and
/// the value mod 10 is the minor version number
///
- public int VersionMadeBy
- {
- get
- {
- return (versionMadeBy & 0xff);
- }
- }
+ public int VersionMadeBy => versionMadeBy & 0xff;
///
/// Get a value indicating this entry is for a DOS/Windows system.
///
public bool IsDOSEntry
- {
- get
- {
- return ((HostSystem == (int)HostSystemID.Msdos) ||
- (HostSystem == (int)HostSystemID.WindowsNT));
- }
- }
+ => (HostSystem == (int)HostSystemID.Msdos)
+ || (HostSystem == (int)HostSystemID.WindowsNT);
///
/// Test the external attributes for this to
@@ -481,7 +403,7 @@ private bool HasDosAttributes(int attributes)
}
///
- /// Gets the compatability information for the external file attribute
+ /// Gets the compatibility information for the external file attribute
/// If the external file attributes are compatible with MS-DOS and can be read
/// by PKZIP for DOS version 2.04g then this value will be zero. Otherwise the value
/// will be non-zero and identify the host system on which the attributes are compatible.
@@ -519,10 +441,7 @@ private bool HasDosAttributes(int attributes)
///
public int HostSystem
{
- get
- {
- return (versionMadeBy >> 8) & 0xff;
- }
+ get => (versionMadeBy >> 8) & 0xff;
set
{
@@ -567,42 +486,26 @@ public int Version
{
// Return recorded version if known.
if (versionToExtract != 0)
- {
- return versionToExtract & 0x00ff; // Only lower order byte. High order is O/S file system.
- }
- else
- {
- int result = 10;
- if (AESKeySize > 0)
- {
- result = ZipConstants.VERSION_AES; // Ver 5.1 = AES
- }
- else if (CentralHeaderRequiresZip64)
- {
- result = ZipConstants.VersionZip64;
- }
- else if (CompressionMethod.Deflated == method)
- {
- result = 20;
- }
- else if (CompressionMethod.BZip2 == method)
- {
- result = ZipConstants.VersionBZip2;
- }
- else if (IsDirectory == true)
- {
- result = 20;
- }
- else if (IsCrypted == true)
- {
- result = 20;
- }
- else if (HasDosAttributes(0x08))
- {
- result = 11;
- }
- return result;
- }
+ // Only lower order byte. High order is O/S file system.
+ return versionToExtract & 0x00ff;
+
+ if (AESKeySize > 0)
+ // Ver 5.1 = AES
+ return ZipConstants.VERSION_AES;
+
+ if (CompressionMethod.BZip2 == method)
+ return ZipConstants.VersionBZip2;
+
+ if (CentralHeaderRequiresZip64)
+ return ZipConstants.VersionZip64;
+
+ if (CompressionMethod.Deflated == method || IsDirectory || IsCrypted)
+ return 20;
+
+ if (HasDosAttributes(0x08))
+ return 11;
+
+ return 10;
}
}
@@ -611,37 +514,21 @@ public int Version
///
/// This is based on the and
/// whether the compression method is supported.
- public bool CanDecompress
- {
- get
- {
- return (Version <= ZipConstants.VersionMadeBy) &&
- ((Version == 10) ||
- (Version == 11) ||
- (Version == 20) ||
- (Version == 45) ||
- (Version == 46) ||
- (Version == 51)) &&
- IsCompressionMethodSupported();
- }
- }
+ public bool CanDecompress
+ => Version <= ZipConstants.VersionMadeBy
+ && (Version == 10 || Version == 11 || Version == 20 || Version == 45 || Version == 46 || Version == 51)
+ && IsCompressionMethodSupported();
///
/// Force this entry to be recorded using Zip64 extensions.
///
- public void ForceZip64()
- {
- forceZip64_ = true;
- }
+ public void ForceZip64() => forceZip64_ = true;
///
/// Get a value indicating whether Zip64 extensions were forced.
///
/// A value of true if Zip64 extensions have been forced on; false if not.
- public bool IsZip64Forced()
- {
- return forceZip64_;
- }
+ public bool IsZip64Forced() => forceZip64_;
///
/// Gets a value indicating if the entry requires Zip64 extensions
@@ -677,13 +564,8 @@ public bool LocalHeaderRequiresZip64
///
/// Get a value indicating whether the central directory entry requires Zip64 extensions to be stored.
///
- public bool CentralHeaderRequiresZip64
- {
- get
- {
- return LocalHeaderRequiresZip64 || (offset >= uint.MaxValue);
- }
- }
+ public bool CentralHeaderRequiresZip64
+ => LocalHeaderRequiresZip64 || (offset >= uint.MaxValue);
///
/// Get/Set DosTime value.
@@ -699,41 +581,39 @@ public long DosTime
{
return 0;
}
- else
- {
- var year = (uint)DateTime.Year;
- var month = (uint)DateTime.Month;
- var day = (uint)DateTime.Day;
- var hour = (uint)DateTime.Hour;
- var minute = (uint)DateTime.Minute;
- var second = (uint)DateTime.Second;
-
- if (year < 1980)
- {
- year = 1980;
- month = 1;
- day = 1;
- hour = 0;
- minute = 0;
- second = 0;
- }
- else if (year > 2107)
- {
- year = 2107;
- month = 12;
- day = 31;
- hour = 23;
- minute = 59;
- second = 59;
- }
- return ((year - 1980) & 0x7f) << 25 |
- (month << 21) |
- (day << 16) |
- (hour << 11) |
- (minute << 5) |
- (second >> 1);
+ var year = (uint)DateTime.Year;
+ var month = (uint)DateTime.Month;
+ var day = (uint)DateTime.Day;
+ var hour = (uint)DateTime.Hour;
+ var minute = (uint)DateTime.Minute;
+ var second = (uint)DateTime.Second;
+
+ if (year < 1980)
+ {
+ year = 1980;
+ month = 1;
+ day = 1;
+ hour = 0;
+ minute = 0;
+ second = 0;
}
+ else if (year > 2107)
+ {
+ year = 2107;
+ month = 12;
+ day = 31;
+ hour = 23;
+ minute = 59;
+ second = 59;
+ }
+
+ return ((year - 1980) & 0x7f) << 25 |
+ (month << 21) |
+ (day << 16) |
+ (hour << 11) |
+ (minute << 5) |
+ (second >> 1);
}
set
@@ -760,10 +640,7 @@ public long DosTime
///
public DateTime DateTime
{
- get
- {
- return dateTime;
- }
+ get => dateTime;
set
{
@@ -783,15 +660,8 @@ public DateTime DateTime
///
public string Name
{
- get
- {
- return name;
- }
-
- internal set
- {
- name = value;
- }
+ get => name;
+ internal set => name = value;
}
///
@@ -801,17 +671,14 @@ internal set
/// The size or -1 if unknown.
///
/// Setting the size before adding an entry to an archive can help
- /// avoid compatability problems with some archivers which dont understand Zip64 extensions.
+ /// avoid compatibility problems with some archivers which don't understand Zip64 extensions.
public long Size
{
- get
- {
- return (known & Known.Size) != 0 ? (long)size : -1L;
- }
+ get => (known & Known.Size) != 0 ? (long)size : -1L;
set
{
- this.size = (ulong)value;
- this.known |= Known.Size;
+ size = (ulong)value;
+ known |= Known.Size;
}
}
@@ -823,14 +690,11 @@ public long Size
///
public long CompressedSize
{
- get
- {
- return (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L;
- }
+ get => (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L;
set
{
- this.compressedSize = (ulong)value;
- this.known |= Known.CompressedSize;
+ compressedSize = (ulong)value;
+ known |= Known.CompressedSize;
}
}
@@ -845,13 +709,10 @@ public long CompressedSize
///
public long Crc
{
- get
- {
- return (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L;
- }
+ get => (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L;
set
{
- if (((ulong)crc & 0xffffffff00000000L) != 0)
+ if ((crc & 0xffffffff00000000L) != 0)
{
throw new ArgumentOutOfRangeException(nameof(value));
}
@@ -861,28 +722,19 @@ public long Crc
}
///
- /// Gets/Sets the compression method. Only Deflated and Stored are supported.
+ /// Gets/Sets the compression method.
///
+ /// Throws exception when set if the method is not valid as per
+ ///
///
/// The compression method for this entry
///
- ///
- ///
public CompressionMethod CompressionMethod
{
- get
- {
- return method;
- }
-
- set
- {
- if (!IsCompressionMethodSupported(value))
- {
- throw new NotSupportedException("Compression method not supported");
- }
- this.method = value;
- }
+ get => method;
+ set => method = !IsCompressionMethodSupported(value)
+ ? throw new NotSupportedException("Compression method not supported")
+ : value;
}
///
@@ -890,13 +742,8 @@ public CompressionMethod CompressionMethod
/// Returns same value as CompressionMethod except when AES encrypting, which
/// places 99 in the method and places the real method in the extra data.
///
- internal CompressionMethod CompressionMethodForHeader
- {
- get
- {
- return (AESKeySize > 0) ? CompressionMethod.WinZipAES : method;
- }
- }
+ internal CompressionMethod CompressionMethodForHeader
+ => (AESKeySize > 0) ? CompressionMethod.WinZipAES : method;
///
/// Gets/Sets the extra data.
@@ -909,12 +756,9 @@ internal CompressionMethod CompressionMethodForHeader
///
public byte[] ExtraData
{
- get
- {
- // TODO: This is slightly safer but less efficient. Think about whether it should change.
- // return (byte[]) extra.Clone();
- return extra;
- }
+ // TODO: This is slightly safer but less efficient. Think about whether it should change.
+ // return (byte[]) extra.Clone();
+ get => extra;
set
{
@@ -986,62 +830,38 @@ public int AESKeySize
/// AES Encryption strength for storage in extra data in entry header.
/// 1 is 128 bit, 2 is 192 bit, 3 is 256 bit.
///
- internal byte AESEncryptionStrength
- {
- get
- {
- return (byte)_aesEncryptionStrength;
- }
- }
+ internal byte AESEncryptionStrength => (byte)_aesEncryptionStrength;
///
/// Returns the length of the salt, in bytes
///
- internal int AESSaltLen
- {
- get
- {
- // Key size -> Salt length: 128 bits = 8 bytes, 192 bits = 12 bytes, 256 bits = 16 bytes.
- return AESKeySize / 16;
- }
- }
+ /// Key size -> Salt length: 128 bits = 8 bytes, 192 bits = 12 bytes, 256 bits = 16 bytes.
+ internal int AESSaltLen => AESKeySize / 16;
///
/// Number of extra bytes required to hold the AES Header fields (Salt, Pwd verify, AuthCode)
///
- internal int AESOverheadSize
- {
- get
- {
- // File format:
- // Bytes Content
- // Variable Salt value
- // 2 Password verification value
- // Variable Encrypted file data
- // 10 Authentication code
- return 12 + AESSaltLen;
- }
- }
+ /// File format:
+ /// Bytes | Content
+ /// ---------+---------------------------
+ /// Variable | Salt value
+ /// 2 | Password verification value
+ /// Variable | Encrypted file data
+ /// 10 | Authentication code
+ internal int AESOverheadSize => 12 + AESSaltLen;
///
/// Number of extra bytes required to hold the encryption header fields.
///
- internal int EncryptionOverheadSize
- {
- get
- {
+ internal int EncryptionOverheadSize =>
+ !IsCrypted
// 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;
- }
- }
+ ? 0
+ : _aesEncryptionStrength == 0
+ // Entry is encrypted using ZipCrypto
+ ? ZipConstants.CryptoHeaderSize
+ // Entry is encrypted using AES
+ : AESOverheadSize;
///
/// Process extra data fields updating the entry based on the contents.
@@ -1144,7 +964,6 @@ internal void ProcessExtraData(bool localHeader)
}
// For AES the method in the entry is 99, and the real compression method is in the extradata
- //
private void ProcessAESExtraData(ZipExtraData extraData)
{
if (extraData.Find(0x9901))
@@ -1172,7 +991,7 @@ private void ProcessAESExtraData(ZipExtraData extraData)
///
/// Gets/Sets the entry comment.
///
- ///
+ ///
/// If comment is longer than 0xffff.
///
///
@@ -1180,14 +999,11 @@ private void ProcessAESExtraData(ZipExtraData extraData)
///
///
/// A comment is only available for entries when read via the class.
- /// The class doesnt have the comment data available.
+ /// The class doesn't have the comment data available.
///
public string Comment
{
- get
- {
- return comment;
- }
+ get => comment;
set
{
// This test is strictly incorrect as the length is in characters
@@ -1196,7 +1012,7 @@ public string Comment
// is definitely invalid, shorter comments may also have an invalid length
// where there are multi-byte characters
// The full test is not possible here however as the code page to apply conversions with
- // isnt available.
+ // isn't available.
if ((value != null) && (value.Length > 0xffff))
{
throw new ArgumentOutOfRangeException(nameof(value), "cannot exceed 65535");
@@ -1216,19 +1032,9 @@ public string Comment
/// Currently only dos/windows attributes are tested in this manner.
/// The trailing slash convention should always be followed.
///
- public bool IsDirectory
- {
- get
- {
- int nameLength = name.Length;
- bool result =
- ((nameLength > 0) &&
- ((name[nameLength - 1] == '/') || (name[nameLength - 1] == '\\'))) ||
- HasDosAttributes(16)
- ;
- return result;
- }
- }
+ public bool IsDirectory
+ => name.Length > 0
+ && (name[name.Length - 1] == '/' || name[name.Length - 1] == '\\') || HasDosAttributes(16);
///
/// Get a value of true if the entry appears to be a file; false otherwise
@@ -1237,22 +1043,13 @@ public bool IsDirectory
/// This only takes account of DOS/Windows attributes. Other operating systems are ignored.
/// For linux and others the result may be incorrect.
///
- public bool IsFile
- {
- get
- {
- return !IsDirectory && !HasDosAttributes(8);
- }
- }
+ public bool IsFile => !IsDirectory && !HasDosAttributes(8);
///
/// Test entry to see if data can be extracted.
///
/// Returns true if data can be extracted for this entry; false otherwise.
- public bool IsCompressionMethodSupported()
- {
- return IsCompressionMethodSupported(CompressionMethod);
- }
+ public bool IsCompressionMethodSupported() => IsCompressionMethodSupported(CompressionMethod);
#region ICloneable Members
@@ -1280,10 +1077,7 @@ public object Clone()
/// Gets a string representation of this ZipEntry.
///
/// A readable textual representation of this
- public override string ToString()
- {
- return name;
- }
+ public override string ToString() => name;
///
/// Test a compression method to see if this library
@@ -1291,13 +1085,10 @@ public override string ToString()
///
/// The compression method to test.
/// Returns true if the compression method is supported; false otherwise
- public static bool IsCompressionMethodSupported(CompressionMethod method)
- {
- return
- (method == CompressionMethod.Deflated) ||
- (method == CompressionMethod.Stored) ||
- (method == CompressionMethod.BZip2);
- }
+ public static bool IsCompressionMethodSupported(CompressionMethod method)
+ => method == CompressionMethod.Deflated
+ || method == CompressionMethod.Stored
+ || method == CompressionMethod.BZip2;
///
/// Cleans a name making it conform to Zip file conventions.
diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntryExtensions.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryExtensions.cs
new file mode 100644
index 000000000..927e94cfe
--- /dev/null
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryExtensions.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ICSharpCode.SharpZipLib.Zip
+{
+ ///
+ /// General ZipEntry helper extensions
+ ///
+ public static class ZipEntryExtensions
+ {
+ ///
+ /// Efficiently check if a flag is set without enum un-/boxing
+ ///
+ ///
+ ///
+ /// Returns whether the flag was set
+ public static bool HasFlag(this ZipEntry entry, GeneralBitFlags flag)
+ => (entry.Flags & (int) flag) != 0;
+
+ ///
+ /// Efficiently set a flag without enum un-/boxing
+ ///
+ ///
+ ///
+ /// Whether the passed flag should be set (1) or cleared (0)
+ public static void SetFlag(this ZipEntry entry, GeneralBitFlags flag, bool enabled = true)
+ => entry.Flags = enabled
+ ? entry.Flags | (int) flag
+ : entry.Flags & ~(int) flag;
+ }
+}
diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
index 66a3fc872..cccac6639 100644
--- a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
+++ b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs
@@ -126,14 +126,15 @@ public string Password
///
/// The entry can only be decompressed if the library supports the zip features required to extract it.
/// See the ZipEntry Version property for more details.
+ ///
+ /// Since uses the local headers for extraction, entries with no compression combined with the
+ /// flag set, cannot be extracted as the end of the entry data cannot be deduced.
///
- public bool CanDecompressEntry
- {
- get
- {
- return (entry != null) && IsEntryCompressionMethodSupported(entry) && entry.CanDecompress;
- }
- }
+ public bool CanDecompressEntry
+ => entry != null
+ && IsEntryCompressionMethodSupported(entry)
+ && entry.CanDecompress
+ && (!entry.HasFlag(GeneralBitFlags.Descriptor) || entry.CompressionMethod != CompressionMethod.Stored || entry.IsCrypted);
///
/// Is the compression method for the specified entry supported?
@@ -142,7 +143,7 @@ public bool CanDecompressEntry
/// Uses entry.CompressionMethodForHeader so that entries of type WinZipAES will be rejected.
///
/// the entry to check.
- /// true if the compression methiod is supported, false if not.
+ /// true if the compression method is supported, false if not.
private static bool IsEntryCompressionMethodSupported(ZipEntry entry)
{
var entryCompressionMethod = entry.CompressionMethodForHeader;
@@ -493,6 +494,14 @@ private int ReadingNotSupported(byte[] destination, int offset, int count)
throw new ZipException("The compression method for this entry is not supported");
}
+ ///
+ /// Handle attempts to read from this entry by throwing an exception
+ ///
+ private int StoredDescriptorEntry(byte[] destination, int offset, int count) =>
+ throw new StreamUnsupportedException(
+ "The combination of Stored compression method and Descriptor flag is not possible to read using ZipInputStream");
+
+
///
/// Perform the initial read on an entry which may include
/// reading encryption headers and setting up inflation.
@@ -503,10 +512,7 @@ private int ReadingNotSupported(byte[] destination, int offset, int count)
/// The actual number of bytes read.
private int InitialRead(byte[] destination, int offset, int count)
{
- if (!CanDecompressEntry)
- {
- throw new ZipException("Library cannot extract this entry. Version required is (" + entry.Version + ")");
- }
+ var usesDescriptor = (entry.Flags & (int)GeneralBitFlags.Descriptor) != 0;
// Handle encryption if required.
if (entry.IsCrypted)
@@ -534,9 +540,9 @@ private int InitialRead(byte[] destination, int offset, int count)
{
csize -= ZipConstants.CryptoHeaderSize;
}
- else if ((entry.Flags & (int)GeneralBitFlags.Descriptor) == 0)
+ else if (!usesDescriptor)
{
- throw new ZipException(string.Format("Entry compressed size {0} too small for encryption", csize));
+ throw new ZipException($"Entry compressed size {csize} too small for encryption");
}
}
else
@@ -544,21 +550,33 @@ private int InitialRead(byte[] destination, int offset, int count)
inputBuffer.CryptoTransform = null;
}
- if ((csize > 0) || ((flags & (int)GeneralBitFlags.Descriptor) != 0))
+ if (csize > 0 || usesDescriptor)
{
- if ((method == CompressionMethod.Deflated) && (inputBuffer.Available > 0))
+ if (method == CompressionMethod.Deflated && inputBuffer.Available > 0)
{
inputBuffer.SetInflaterInput(inf);
}
- internalReader = new ReadDataHandler(BodyRead);
+ // It's not possible to know how many bytes to read when using "Stored" compression (unless using encryption)
+ if (!entry.IsCrypted && method == CompressionMethod.Stored && usesDescriptor)
+ {
+ internalReader = StoredDescriptorEntry;
+ return StoredDescriptorEntry(destination, offset, count);
+ }
+
+ if (!CanDecompressEntry)
+ {
+ internalReader = ReadingNotSupported;
+ return ReadingNotSupported(destination, offset, count);
+ }
+
+ internalReader = BodyRead;
return BodyRead(destination, offset, count);
}
- else
- {
- internalReader = new ReadDataHandler(ReadingNotAvailable);
- return 0;
- }
+
+
+ internalReader = ReadingNotAvailable;
+ return 0;
}
///
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
index 8be25a4dc..19da3adf6 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs
@@ -227,20 +227,14 @@ public void Encryption(ZipEncryptionMethod encryptionMethod)
[Category("Zip")]
public void CreateExceptions()
{
- var fastZip = new FastZip();
- string tempFilePath = GetTempFilePath();
- Assert.IsNotNull(tempFilePath, "No permission to execute this test?");
-
Assert.Throws(() =>
{
- string addFile = Path.Combine(tempFilePath, "test.zip");
- try
- {
- fastZip.CreateZip(addFile, @"z:\doesnt exist", false, null);
- }
- finally
+ using (var tempDir = new Utils.TempDir())
{
- File.Delete(addFile);
+ var fastZip = new FastZip();
+ var badPath = Path.Combine(Path.GetTempPath(), Utils.GetDummyFileName());
+ var addFile = Path.Combine(tempDir.Fullpath, "test.zip");
+ fastZip.CreateZip(addFile, badPath, false, null);
}
});
}
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
index 60d7a5709..7a336592a 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs
@@ -520,5 +520,41 @@ public void AddingAnAESEntryWithNoPasswordShouldThrow()
}
}
}
+
+ [Test]
+ [Category("Zip")]
+ public void ShouldThrowDescriptiveExceptionOnUncompressedDescriptorEntry()
+ {
+ using (var ms = new MemoryStreamWithoutSeek())
+ {
+ using (var zos = new ZipOutputStream(ms))
+ {
+ zos.IsStreamOwner = false;
+ var entry = new ZipEntry("testentry");
+ entry.CompressionMethod = CompressionMethod.Stored;
+ entry.Flags |= (int)GeneralBitFlags.Descriptor;
+ zos.PutNextEntry(entry);
+ zos.Write(new byte[1], 0, 1);
+ zos.CloseEntry();
+ }
+
+ // Patch the Compression Method, since ZipOutputStream automatically changes it to Deflate when descriptors are used
+ ms.Seek(8, SeekOrigin.Begin);
+ ms.WriteByte((byte)CompressionMethod.Stored);
+ ms.Seek(0, SeekOrigin.Begin);
+
+ using (var zis = new ZipInputStream(ms))
+ {
+ zis.IsStreamOwner = false;
+ var buf = new byte[32];
+ zis.GetNextEntry();
+
+ Assert.Throws(typeof(StreamUnsupportedException), () =>
+ {
+ zis.Read(buf, 0, buf.Length);
+ });
+ }
+ }
+ }
}
}