ICSharpCode.SharpZipLib.Zip.ZipEntry - Coverage Report

# Summary

Class: | ICSharpCode.SharpZipLib.Zip.ZipEntry
Assembly: | ICSharpCode.SharpZipLib
File(s): | C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\ZipEntry.cs
Covered lines: | 219
Uncovered lines: | 69
Coverable lines: | 288
Total lines: | 1175
Line coverage: | 76%
Branch coverage: | 59.5%

# Metrics

Method | Cyclomatic Complexity | Sequence Coverage | Branch Coverage
--- | --- | --- | ---
.ctor(...) | 1 | 100 | 100
.ctor(...) | 1 | 100 | 100
.ctor(...) | 5 | 87.5 | 77.78
.ctor(...) | 3 | 96.15 | 60
HasDosAttributes(...) | 4 | 100 | 100
ForceZip64() | 1 | 100 | 100
IsZip64Forced() | 1 | 100 | 100
ProcessExtraData(...) | 11 | 72.22 | 66.67
GetDateTime(...) | 5 | 90 | 33.33
ProcessAESExtraData(...) | 3 | 0 | 0
IsCompressionMethodSupported() | 1 | 100 | 100
Clone() | 2 | 100 | 100
ToString() | 1 | 0 | 0
IsCompressionMethodSupported(...) | 2 | 100 | 100
CleanName(...) | 5 | 62.5 | 55.56

# File(s)

## C:\Users\Neil\Documents\Visual Studio 2015\Projects\icsharpcode\SZL_master\ICSharpCode.SharpZipLib\Zip\ZipEntry.cs

| # | Line |  | Line coverage
--- | --- | --- | --- | ---
|  | `1` |  | `using System;`
|  | `2` |  | `using System.IO;`
|  | `3` |  | ``
|  | `4` |  | `namespace ICSharpCode.SharpZipLib.Zip`
|  | `5` |  | `{`
|  | `6` |  | `/// <summary>`
|  | `7` |  | `/// Defines known values for the <see cref="HostSystemID"/> property.`
|  | `8` |  | `/// </summary>`
|  | `9` |  | `public enum HostSystemID`
|  | `10` |  | `{`
|  | `11` |  | `/// <summary>`
|  | `12` |  | `/// Host system = MSDOS`
|  | `13` |  | `/// </summary>`
|  | `14` |  | `Msdos = 0,`
|  | `15` |  | `/// <summary>`
|  | `16` |  | `/// Host system = Amiga`
|  | `17` |  | `/// </summary>`
|  | `18` |  | `Amiga = 1,`
|  | `19` |  | `/// <summary>`
|  | `20` |  | `/// Host system = Open VMS`
|  | `21` |  | `/// </summary>`
|  | `22` |  | `OpenVms = 2,`
|  | `23` |  | `/// <summary>`
|  | `24` |  | `/// Host system = Unix`
|  | `25` |  | `/// </summary>`
|  | `26` |  | `Unix = 3,`
|  | `27` |  | `/// <summary>`
|  | `28` |  | `/// Host system = VMCms`
|  | `29` |  | `/// </summary>`
|  | `30` |  | `VMCms = 4,`
|  | `31` |  | `/// <summary>`
|  | `32` |  | `/// Host system = Atari ST`
|  | `33` |  | `/// </summary>`
|  | `34` |  | `AtariST = 5,`
|  | `35` |  | `/// <summary>`
|  | `36` |  | `/// Host system = OS2`
|  | `37` |  | `/// </summary>`
|  | `38` |  | `OS2 = 6,`
|  | `39` |  | `/// <summary>`
|  | `40` |  | `/// Host system = Macintosh`
|  | `41` |  | `/// </summary>`
|  | `42` |  | `Macintosh = 7,`
|  | `43` |  | `/// <summary>`
|  | `44` |  | `/// Host system = ZSystem`
|  | `45` |  | `/// </summary>`
|  | `46` |  | `ZSystem = 8,`
|  | `47` |  | `/// <summary>`
|  | `48` |  | `/// Host system = Cpm`
|  | `49` |  | `/// </summary>`
|  | `50` |  | `Cpm = 9,`
|  | `51` |  | `/// <summary>`
|  | `52` |  | `/// Host system = Windows NT`
|  | `53` |  | `/// </summary>`
|  | `54` |  | `WindowsNT = 10,`
|  | `55` |  | `/// <summary>`
|  | `56` |  | `/// Host system = MVS`
|  | `57` |  | `/// </summary>`
|  | `58` |  | `MVS = 11,`
|  | `59` |  | `/// <summary>`
|  | `60` |  | `/// Host system = VSE`
|  | `61` |  | `/// </summary>`
|  | `62` |  | `Vse = 12,`
|  | `63` |  | `/// <summary>`
|  | `64` |  | `/// Host system = Acorn RISC`
|  | `65` |  | `/// </summary>`
|  | `66` |  | `AcornRisc = 13,`
|  | `67` |  | `/// <summary>`
|  | `68` |  | `/// Host system = VFAT`
|  | `69` |  | `/// </summary>`
|  | `70` |  | `Vfat = 14,`
|  | `71` |  | `/// <summary>`
|  | `72` |  | `/// Host system = Alternate MVS`
|  | `73` |  | `/// </summary>`
|  | `74` |  | `AlternateMvs = 15,`
|  | `75` |  | `/// <summary>`
|  | `76` |  | `/// Host system = BEOS`
|  | `77` |  | `/// </summary>`
|  | `78` |  | `BeOS = 16,`
|  | `79` |  | `/// <summary>`
|  | `80` |  | `/// Host system = Tandem`
|  | `81` |  | `/// </summary>`
|  | `82` |  | `Tandem = 17,`
|  | `83` |  | `/// <summary>`
|  | `84` |  | `/// Host system = OS400`
|  | `85` |  | `/// </summary>`
|  | `86` |  | `OS400 = 18,`
|  | `87` |  | `/// <summary>`
|  | `88` |  | `/// Host system = OSX`
|  | `89` |  | `/// </summary>`
|  | `90` |  | `OSX = 19,`
|  | `91` |  | `/// <summary>`
|  | `92` |  | `/// Host system = WinZIP AES`
|  | `93` |  | `/// </summary>`
|  | `94` |  | `WinZipAES = 99,`
|  | `95` |  | `}`
|  | `96` |  | ``
|  | `97` |  | `/// <summary>`
|  | `98` |  | `/// This class represents an entry in a zip archive. This can be a file`
|  | `99` |  | `/// or a directory`
|  | `100` |  | `/// ZipFile and ZipInputStream will give you instances of this class as`
|  | `101` |  | `/// information about the members in an archive. ZipOutputStream`
|  | `102` |  | `/// uses an instance of this class when creating an entry in a Zip file.`
|  | `103` |  | `/// <br/>`
|  | `104` |  | `/// <br/>Author of the original java version : Jochen Hoenicke`
|  | `105` |  | `/// </summary>`
|  | `106` |  | `public class ZipEntry : ICloneable`
|  | `107` |  | `{`
|  | `108` |  | `[Flags]`
|  | `109` |  | `enum Known : byte`
|  | `110` |  | `{`
|  | `111` |  | `None = 0,`
|  | `112` |  | `Size = 0x01,`
|  | `113` |  | `CompressedSize = 0x02,`
|  | `114` |  | `Crc = 0x04,`
|  | `115` |  | `Time = 0x08,`
|  | `116` |  | `ExternalAttributes = 0x10,`
|  | `117` |  | `}`
|  | `118` |  | ``
|  | `119` |  | `#region Constructors`
|  | `120` |  | `/// <summary>`
|  | `121` |  | `/// Creates a zip entry with the given name.`
|  | `122` |  | `/// </summary>`
|  | `123` |  | `/// <param name="name">`
|  | `124` |  | `/// The name for this entry. Can include directory components.`
|  | `125` |  | `/// The convention for names is 'unix' style paths with relative names only.`
|  | `126` |  | `/// There are with no device names and path elements are separated by '/' characters.`
|  | `127` |  | `/// </param>`
|  | `128` |  | `/// <exception cref="ArgumentNullException">`
|  | `129` |  | `/// The name passed is null`
|  | `130` |  | `/// </exception>`
|  | `131` |  | `public ZipEntry(string name)`
| 65841 | `132` |  | `: this(name, 0, ZipConstants.VersionMadeBy, CompressionMethod.Deflated)`
|  | `133` |  | `{`
| 65840 | `134` |  | `}`
|  | `135` |  | ``
|  | `136` |  | `/// <summary>`
|  | `137` |  | `/// Creates a zip entry with the given name and version required to extract`
|  | `138` |  | `/// </summary>`
|  | `139` |  | `/// <param name="name">`
|  | `140` |  | `/// The name for this entry. Can include directory components.`
|  | `141` |  | `/// The convention for names is 'unix' style paths with no device names and`
|  | `142` |  | `/// path elements separated by '/' characters. This is not enforced see <see cref="CleanName(string)">CleanName</se`
|  | `143` |  | `/// on how to ensure names are valid if this is desired.`
|  | `144` |  | `/// </param>`
|  | `145` |  | `/// <param name="versionRequiredToExtract">`
|  | `146` |  | `/// The minimum 'feature version' required this entry`
|  | `147` |  | `/// </param>`
|  | `148` |  | `/// <exception cref="ArgumentNullException">`
|  | `149` |  | `/// The name passed is null`
|  | `150` |  | `/// </exception>`
|  | `151` |  | `internal ZipEntry(string name, int versionRequiredToExtract)`
| 81 | `152` |  | `: this(name, versionRequiredToExtract, ZipConstants.VersionMadeBy,`
| 81 | `153` |  | `CompressionMethod.Deflated)`
|  | `154` |  | `{`
| 81 | `155` |  | `}`
|  | `156` |  | ``
|  | `157` |  | `/// <summary>`
|  | `158` |  | `/// Initializes an entry with the given name and made by information`
|  | `159` |  | `/// </summary>`
|  | `160` |  | `/// <param name="name">Name for this entry</param>`
|  | `161` |  | `/// <param name="madeByInfo">Version and HostSystem Information</param>`
|  | `162` |  | `/// <param name="versionRequiredToExtract">Minimum required zip feature version required to extract this entry</para`
|  | `163` |  | `/// <param name="method">Compression method for this entry.</param>`
|  | `164` |  | `/// <exception cref="ArgumentNullException">`
|  | `165` |  | `/// The name passed is null`
|  | `166` |  | `/// </exception>`
|  | `167` |  | `/// <exception cref="ArgumentOutOfRangeException">`
|  | `168` |  | `/// versionRequiredToExtract should be 0 (auto-calculate) or > 10`
|  | `169` |  | `/// </exception>`
|  | `170` |  | `/// <remarks>`
|  | `171` |  | `/// This constructor is used by the ZipFile class when reading from the central header`
|  | `172` |  | `/// It is not generally useful, use the constructor specifying the name only.`
|  | `173` |  | `/// </remarks>`
| 131878 | `174` |  | `internal ZipEntry(string name, int versionRequiredToExtract, int madeByInfo,`
| 131878 | `175` |  | `CompressionMethod method)`
|  | `176` |  | `{`
| 131878 | `177` |  | `if (name == null) {`
| 1 | `178` |  | `throw new ArgumentNullException(nameof(name));`
|  | `179` |  | `}`
|  | `180` |  | ``
| 131877 | `181` |  | `if (name.Length > 0xffff) {`
| 0 | `182` |  | `throw new ArgumentException("Name is too long", nameof(name));`
|  | `183` |  | `}`
|  | `184` |  | ``
| 131877 | `185` |  | `if ((versionRequiredToExtract != 0) && (versionRequiredToExtract < 10)) {`
| 0 | `186` |  | `throw new ArgumentOutOfRangeException(nameof(versionRequiredToExtract));`
|  | `187` |  | `}`
|  | `188` |  | ``
| 131877 | `189` |  | `this.DateTime = DateTime.Now;`
| 131877 | `190` |  | `this.name = CleanName(name);`
| 131877 | `191` |  | `this.versionMadeBy = (ushort)madeByInfo;`
| 131877 | `192` |  | `this.versionToExtract = (ushort)versionRequiredToExtract;`
| 131877 | `193` |  | `this.method = method;`
| 131877 | `194` |  | `}`
|  | `195` |  | ``
|  | `196` |  | `/// <summary>`
|  | `197` |  | `/// Creates a deep copy of the given zip entry.`
|  | `198` |  | `/// </summary>`
|  | `199` |  | `/// <param name="entry">`
|  | `200` |  | `/// The entry to copy.`
|  | `201` |  | `/// </param>`
|  | `202` |  | `[Obsolete("Use Clone instead")]`
| 1 | `203` |  | `public ZipEntry(ZipEntry entry)`
|  | `204` |  | `{`
| 1 | `205` |  | `if (entry == null) {`
| 0 | `206` |  | `throw new ArgumentNullException(nameof(entry));`
|  | `207` |  | `}`
|  | `208` |  | ``
| 1 | `209` |  | `known = entry.known;`
| 1 | `210` |  | `name = entry.name;`
| 1 | `211` |  | `size = entry.size;`
| 1 | `212` |  | `compressedSize = entry.compressedSize;`
| 1 | `213` |  | `crc = entry.crc;`
| 1 | `214` |  | `dosTime = entry.dosTime;`
| 1 | `215` |  | `dateTime = entry.dateTime;`
| 1 | `216` |  | `method = entry.method;`
| 1 | `217` |  | `comment = entry.comment;`
| 1 | `218` |  | `versionToExtract = entry.versionToExtract;`
| 1 | `219` |  | `versionMadeBy = entry.versionMadeBy;`
| 1 | `220` |  | `externalFileAttributes = entry.externalFileAttributes;`
| 1 | `221` |  | `flags = entry.flags;`
|  | `222` |  | ``
| 1 | `223` |  | `zipFileIndex = entry.zipFileIndex;`
| 1 | `224` |  | `offset = entry.offset;`
|  | `225` |  | ``
| 1 | `226` |  | `forceZip64_ = entry.forceZip64_;`
|  | `227` |  | ``
| 1 | `228` |  | `if (entry.extra != null) {`
| 1 | `229` |  | `extra = new byte[entry.extra.Length];`
| 1 | `230` |  | `Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length);`
|  | `231` |  | `}`
| 1 | `232` |  | `}`
|  | `233` |  | ``
|  | `234` |  | `#endregion`
|  | `235` |  | ``
|  | `236` |  | `/// <summary>`
|  | `237` |  | `/// Get a value indicating wether the entry has a CRC value available.`
|  | `238` |  | `/// </summary>`
|  | `239` |  | `public bool HasCrc {`
|  | `240` |  | `get {`
| 65754 | `241` |  | `return (known & Known.Crc) != 0;`
|  | `242` |  | `}`
|  | `243` |  | `}`
|  | `244` |  | ``
|  | `245` |  | `/// <summary>`
|  | `246` |  | `/// Get/Set flag indicating if entry is encrypted.`
|  | `247` |  | `/// A simple helper routine to aid interpretation of <see cref="Flags">flags</see>`
|  | `248` |  | `/// </summary>`
|  | `249` |  | `/// <remarks>This is an assistant that interprets the <see cref="Flags">flags</see> property.</remarks>`
|  | `250` |  | `public bool IsCrypted {`
|  | `251` |  | `get {`
| 592001 | `252` |  | `return (flags & 1) != 0;`
|  | `253` |  | `}`
|  | `254` |  | `set {`
| 65738 | `255` |  | `if (value) {`
| 38 | `256` |  | `flags |= 1;`
| 38 | `257` |  | `} else {`
| 65700 | `258` |  | `flags &= ~1;`
|  | `259` |  | `}`
| 65700 | `260` |  | `}`
|  | `261` |  | `}`
|  | `262` |  | ``
|  | `263` |  | `/// <summary>`
|  | `264` |  | `/// Get / set a flag indicating wether entry name and comment text are`
|  | `265` |  | `/// encoded in <a href="http://www.unicode.org">unicode UTF8</a>.`
|  | `266` |  | `/// </summary>`
|  | `267` |  | `/// <remarks>This is an assistant that interprets the <see cref="Flags">flags</see> property.</remarks>`
|  | `268` |  | `public bool IsUnicodeText {`
|  | `269` |  | `get {`
| 4 | `270` |  | `return (flags & (int)GeneralBitFlags.UnicodeText) != 0;`
|  | `271` |  | `}`
|  | `272` |  | `set {`
| 177 | `273` |  | `if (value) {`
| 8 | `274` |  | `flags |= (int)GeneralBitFlags.UnicodeText;`
| 8 | `275` |  | `} else {`
| 169 | `276` |  | `flags &= ~(int)GeneralBitFlags.UnicodeText;`
|  | `277` |  | `}`
| 169 | `278` |  | `}`
|  | `279` |  | `}`
|  | `280` |  | ``
|  | `281` |  | `/// <summary>`
|  | `282` |  | `/// Value used during password checking for PKZIP 2.0 / 'classic' encryption.`
|  | `283` |  | `/// </summary>`
|  | `284` |  | `internal byte CryptoCheckValue {`
|  | `285` |  | `get {`
| 34 | `286` |  | `return cryptoCheckValue_;`
|  | `287` |  | `}`
|  | `288` |  | ``
|  | `289` |  | `set {`
| 66037 | `290` |  | `cryptoCheckValue_ = value;`
| 66037 | `291` |  | `}`
|  | `292` |  | `}`
|  | `293` |  | ``
|  | `294` |  | `/// <summary>`
|  | `295` |  | `/// Get/Set general purpose bit flag for entry`
|  | `296` |  | `/// </summary>`
|  | `297` |  | `/// <remarks>`
|  | `298` |  | `/// General purpose bit flag<br/>`
|  | `299` |  | `/// <br/>`
|  | `300` |  | `/// Bit 0: If set, indicates the file is encrypted<br/>`
|  | `301` |  | `/// Bit 1-2 Only used for compression type 6 Imploding, and 8, 9 deflating<br/>`
|  | `302` |  | `/// Imploding:<br/>`
|  | `303` |  | `/// Bit 1 if set indicates an 8K sliding dictionary was used. If clear a 4k dictionary was used<br/>`
|  | `304` |  | `/// Bit 2 if set indicates 3 Shannon-Fanno trees were used to encode the sliding dictionary, 2 otherwise<br/>`
|  | `305` |  | `/// <br/>`
|  | `306` |  | `/// Deflating:<br/>`
|  | `307` |  | `/// Bit 2 Bit 1<br/>`
|  | `308` |  | `/// 0 0 Normal compression was used<br/>`
|  | `309` |  | `/// 0 1 Maximum compression was used<br/>`
|  | `310` |  | `/// 1 0 Fast compression was used<br/>`
|  | `311` |  | `/// 1 1 Super fast compression was used<br/>`
|  | `312` |  | `/// <br/>`
|  | `313` |  | `/// Bit 3: If set, the fields crc-32, compressed size`
|  | `314` |  | `/// and uncompressed size are were not able to be written during zip file creation`
|  | `315` |  | `/// The correct values are held in a data descriptor immediately following the compressed data. <br/>`
|  | `316` |  | `/// Bit 4: Reserved for use by PKZIP for enhanced deflating<br/>`
|  | `317` |  | `/// Bit 5: If set indicates the file contains compressed patch data<br/>`
|  | `318` |  | `/// Bit 6: If set indicates strong encryption was used.<br/>`
|  | `319` |  | `/// Bit 7-10: Unused or reserved<br/>`
|  | `320` |  | `/// Bit 11: If set the name and comments for this entry are in <a href="http://www.unicode.org">unicode</a>.<br/>`
|  | `321` |  | `/// Bit 12-15: Unused or reserved<br/>`
|  | `322` |  | `/// </remarks>`
|  | `323` |  | `/// <seealso cref="IsUnicodeText"></seealso>`
|  | `324` |  | `/// <seealso cref="IsCrypted"></seealso>`
|  | `325` |  | `public int Flags {`
|  | `326` |  | `get {`
| 395994 | `327` |  | `return flags;`
|  | `328` |  | `}`
|  | `329` |  | `set {`
| 66249 | `330` |  | `flags = value;`
| 66249 | `331` |  | `}`
|  | `332` |  | `}`
|  | `333` |  | ``
|  | `334` |  | `/// <summary>`
|  | `335` |  | `/// Get/Set index of this entry in Zip file`
|  | `336` |  | `/// </summary>`
|  | `337` |  | `/// <remarks>This is only valid when the entry is part of a <see cref="ZipFile"></see></remarks>`
|  | `338` |  | `public long ZipFileIndex {`
|  | `339` |  | `get {`
| 65933 | `340` |  | `return zipFileIndex;`
|  | `341` |  | `}`
|  | `342` |  | `set {`
| 65956 | `343` |  | `zipFileIndex = value;`
| 65956 | `344` |  | `}`
|  | `345` |  | `}`
|  | `346` |  | ``
|  | `347` |  | `/// <summary>`
|  | `348` |  | `/// Get/set offset for use in central header`
|  | `349` |  | `/// </summary>`
|  | `350` |  | `public long Offset {`
|  | `351` |  | `get {`
| 396693 | `352` |  | `return offset;`
|  | `353` |  | `}`
|  | `354` |  | `set {`
| 131833 | `355` |  | `offset = value;`
| 131833 | `356` |  | `}`
|  | `357` |  | `}`
|  | `358` |  | ``
|  | `359` |  | `/// <summary>`
|  | `360` |  | `/// Get/Set external file attributes as an integer.`
|  | `361` |  | `/// The values of this are operating system dependant see`
|  | `362` |  | `/// <see cref="HostSystem">HostSystem</see> for details`
|  | `363` |  | `/// </summary>`
|  | `364` |  | `public int ExternalFileAttributes {`
|  | `365` |  | `get {`
| 527438 | `366` |  | `if ((known & Known.ExternalAttributes) == 0) {`
| 65824 | `367` |  | `return -1;`
|  | `368` |  | `} else {`
| 461614 | `369` |  | `return externalFileAttributes;`
|  | `370` |  | `}`
|  | `371` |  | `}`
|  | `372` |  | ``
|  | `373` |  | `set {`
| 65965 | `374` |  | `externalFileAttributes = value;`
| 65965 | `375` |  | `known |= Known.ExternalAttributes;`
| 65965 | `376` |  | `}`
|  | `377` |  | `}`
|  | `378` |  | ``
|  | `379` |  | `/// <summary>`
|  | `380` |  | `/// Get the version made by for this entry or zero if unknown.`
|  | `381` |  | `/// The value / 10 indicates the major version number, and`
|  | `382` |  | `/// the value mod 10 is the minor version number`
|  | `383` |  | `/// </summary>`
|  | `384` |  | `public int VersionMadeBy {`
|  | `385` |  | `get {`
| 0 | `386` |  | `return (versionMadeBy & 0xff);`
|  | `387` |  | `}`
|  | `388` |  | `}`
|  | `389` |  | ``
|  | `390` |  | `/// <summary>`
|  | `391` |  | `/// Get a value indicating this entry is for a DOS/Windows system.`
|  | `392` |  | `/// </summary>`
|  | `393` |  | `public bool IsDOSEntry {`
|  | `394` |  | `get {`
| 2 | `395` |  | `return ((HostSystem == (int)HostSystemID.Msdos) ||`
| 2 | `396` |  | `(HostSystem == (int)HostSystemID.WindowsNT));`
|  | `397` |  | `}`
|  | `398` |  | `}`
|  | `399` |  | ``
|  | `400` |  | `/// <summary>`
|  | `401` |  | `/// Test the external attributes for this <see cref="ZipEntry"/> to`
|  | `402` |  | `/// see if the external attributes are Dos based (including WINNT and variants)`
|  | `403` |  | `/// and match the values`
|  | `404` |  | `/// </summary>`
|  | `405` |  | `/// <param name="attributes">The attributes to test.</param>`
|  | `406` |  | `/// <returns>Returns true if the external attributes are known to be DOS/Windows`
|  | `407` |  | `/// based and have the same attributes set as the value passed.</returns>`
|  | `408` |  | `bool HasDosAttributes(int attributes)`
|  | `409` |  | `{`
| 920886 | `410` |  | `bool result = false;`
| 920886 | `411` |  | `if ((known & Known.ExternalAttributes) != 0) {`
| 461462 | `412` |  | `result |= (((HostSystem == (int)HostSystemID.Msdos) ||`
| 461462 | `413` |  | `(HostSystem == (int)HostSystemID.WindowsNT)) &&`
| 461462 | `414` |  | `(ExternalFileAttributes & attributes) == attributes);`
|  | `415` |  | `}`
| 920886 | `416` |  | `return result;`
|  | `417` |  | `}`
|  | `418` |  | ``
|  | `419` |  | `/// <summary>`
|  | `420` |  | `/// Gets the compatability information for the <see cref="ExternalFileAttributes">external file attribute</see>`
|  | `421` |  | `/// If the external file attributes are compatible with MS-DOS and can be read`
|  | `422` |  | `/// by PKZIP for DOS version 2.04g then this value will be zero. Otherwise the value`
|  | `423` |  | `/// will be non-zero and identify the host system on which the attributes are compatible.`
|  | `424` |  | `/// </summary>`
|  | `425` |  | `///`
|  | `426` |  | `/// <remarks>`
|  | `427` |  | `/// The values for this as defined in the Zip File format and by others are shown below. The values are somewhat`
|  | `428` |  | `/// misleading in some cases as they are not all used as shown. You should consult the relevant documentation`
|  | `429` |  | `/// to obtain up to date and correct information. The modified appnote by the infozip group is`
|  | `430` |  | `/// particularly helpful as it documents a lot of peculiarities. The document is however a little dated.`
|  | `431` |  | `/// <list type="table">`
|  | `432` |  | `/// <item>0 - MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)</item>`
|  | `433` |  | `/// <item>1 - Amiga</item>`
|  | `434` |  | `/// <item>2 - OpenVMS</item>`
|  | `435` |  | `/// <item>3 - Unix</item>`
|  | `436` |  | `/// <item>4 - VM/CMS</item>`
|  | `437` |  | `/// <item>5 - Atari ST</item>`
|  | `438` |  | `/// <item>6 - OS/2 HPFS</item>`
|  | `439` |  | `/// <item>7 - Macintosh</item>`
|  | `440` |  | `/// <item>8 - Z-System</item>`
|  | `441` |  | `/// <item>9 - CP/M</item>`
|  | `442` |  | `/// <item>10 - Windows NTFS</item>`
|  | `443` |  | `/// <item>11 - MVS (OS/390 - Z/OS)</item>`
|  | `444` |  | `/// <item>12 - VSE</item>`
|  | `445` |  | `/// <item>13 - Acorn Risc</item>`
|  | `446` |  | `/// <item>14 - VFAT</item>`
|  | `447` |  | `/// <item>15 - Alternate MVS</item>`
|  | `448` |  | `/// <item>16 - BeOS</item>`
|  | `449` |  | `/// <item>17 - Tandem</item>`
|  | `450` |  | `/// <item>18 - OS/400</item>`
|  | `451` |  | `/// <item>19 - OS/X (Darwin)</item>`
|  | `452` |  | `/// <item>99 - WinZip AES</item>`
|  | `453` |  | `/// <item>remainder - unused</item>`
|  | `454` |  | `/// </list>`
|  | `455` |  | `/// </remarks>`
|  | `456` |  | `public int HostSystem {`
|  | `457` |  | `get {`
| 461464 | `458` |  | `return (versionMadeBy >> 8) & 0xff;`
|  | `459` |  | `}`
|  | `460` |  | ``
|  | `461` |  | `set {`
| 0 | `462` |  | `versionMadeBy &= 0xff;`
| 0 | `463` |  | `versionMadeBy |= (ushort)((value & 0xff) << 8);`
| 0 | `464` |  | `}`
|  | `465` |  | `}`
|  | `466` |  | ``
|  | `467` |  | `/// <summary>`
|  | `468` |  | `/// Get minimum Zip feature version required to extract this entry`
|  | `469` |  | `/// </summary>`
|  | `470` |  | `/// <remarks>`
|  | `471` |  | `/// Minimum features are defined as:<br/>`
|  | `472` |  | `/// 1.0 - Default value<br/>`
|  | `473` |  | `/// 1.1 - File is a volume label<br/>`
|  | `474` |  | `/// 2.0 - File is a folder/directory<br/>`
|  | `475` |  | `/// 2.0 - File is compressed using Deflate compression<br/>`
|  | `476` |  | `/// 2.0 - File is encrypted using traditional encryption<br/>`
|  | `477` |  | `/// 2.1 - File is compressed using Deflate64<br/>`
|  | `478` |  | `/// 2.5 - File is compressed using PKWARE DCL Implode<br/>`
|  | `479` |  | `/// 2.7 - File is a patch data set<br/>`
|  | `480` |  | `/// 4.5 - File uses Zip64 format extensions<br/>`
|  | `481` |  | `/// 4.6 - File is compressed using BZIP2 compression<br/>`
|  | `482` |  | `/// 5.0 - File is encrypted using DES<br/>`
|  | `483` |  | `/// 5.0 - File is encrypted using 3DES<br/>`
|  | `484` |  | `/// 5.0 - File is encrypted using original RC2 encryption<br/>`
|  | `485` |  | `/// 5.0 - File is encrypted using RC4 encryption<br/>`
|  | `486` |  | `/// 5.1 - File is encrypted using AES encryption<br/>`
|  | `487` |  | `/// 5.1 - File is encrypted using corrected RC2 encryption<br/>`
|  | `488` |  | `/// 5.1 - File is encrypted using corrected RC2-64 encryption<br/>`
|  | `489` |  | `/// 6.1 - File is encrypted using non-OAEP key wrapping<br/>`
|  | `490` |  | `/// 6.2 - Central directory encryption (not confirmed yet)<br/>`
|  | `491` |  | `/// 6.3 - File is compressed using LZMA<br/>`
|  | `492` |  | `/// 6.3 - File is compressed using PPMD+<br/>`
|  | `493` |  | `/// 6.3 - File is encrypted using Blowfish<br/>`
|  | `494` |  | `/// 6.3 - File is encrypted using Twofish<br/>`
|  | `495` |  | `/// </remarks>`
|  | `496` |  | `/// <seealso cref="CanDecompress"></seealso>`
|  | `497` |  | `public int Version {`
|  | `498` |  | `get {`
|  | `499` |  | `// Return recorded version if known.`
| 198066 | `500` |  | `if (versionToExtract != 0) {`
| 66394 | `501` |  | `return versionToExtract & 0x00ff; // Only lower order byte. High order is O/S file system.`
|  | `502` |  | `} else {`
| 131672 | `503` |  | `int result = 10;`
| 131672 | `504` |  | `if (AESKeySize > 0) {`
| 0 | `505` |  | `result = ZipConstants.VERSION_AES; // Ver 5.1 = AES`
| 131672 | `506` |  | `} else if (CentralHeaderRequiresZip64) {`
| 247 | `507` |  | `result = ZipConstants.VersionZip64;`
| 131672 | `508` |  | `} else if (CompressionMethod.Deflated == method) {`
| 321 | `509` |  | `result = 20;`
| 131425 | `510` |  | `} else if (IsDirectory == true) {`
| 0 | `511` |  | `result = 20;`
| 131104 | `512` |  | `} else if (IsCrypted == true) {`
| 0 | `513` |  | `result = 20;`
| 131104 | `514` |  | `} else if (HasDosAttributes(0x08)) {`
| 0 | `515` |  | `result = 11;`
|  | `516` |  | `}`
| 131672 | `517` |  | `return result;`
|  | `518` |  | `}`
|  | `519` |  | `}`
|  | `520` |  | `}`
|  | `521` |  | ``
|  | `522` |  | `/// <summary>`
|  | `523` |  | `/// Get a value indicating whether this entry can be decompressed by the library.`
|  | `524` |  | `/// </summary>`
|  | `525` |  | `/// <remarks>This is based on the <see cref="Version"></see> and`
|  | `526` |  | `/// wether the <see cref="IsCompressionMethodSupported()">compression method</see> is supported.</remarks>`
|  | `527` |  | `public bool CanDecompress {`
|  | `528` |  | `get {`
| 73 | `529` |  | `return (Version <= ZipConstants.VersionMadeBy) &&`
| 73 | `530` |  | `((Version == 10) ||`
| 73 | `531` |  | `(Version == 11) ||`
| 73 | `532` |  | `(Version == 20) ||`
| 73 | `533` |  | `(Version == 45) ||`
| 73 | `534` |  | `(Version == 51)) &&`
| 73 | `535` |  | `IsCompressionMethodSupported();`
|  | `536` |  | `}`
|  | `537` |  | `}`
|  | `538` |  | ``
|  | `539` |  | `/// <summary>`
|  | `540` |  | `/// Force this entry to be recorded using Zip64 extensions.`
|  | `541` |  | `/// </summary>`
|  | `542` |  | `public void ForceZip64()`
|  | `543` |  | `{`
| 124 | `544` |  | `forceZip64_ = true;`
| 124 | `545` |  | `}`
|  | `546` |  | ``
|  | `547` |  | `/// <summary>`
|  | `548` |  | `/// Get a value indicating wether Zip64 extensions were forced.`
|  | `549` |  | `/// </summary>`
|  | `550` |  | `/// <returns>A <see cref="bool"/> value of true if Zip64 extensions have been forced on; false if not.</returns>`
|  | `551` |  | `public bool IsZip64Forced()`
|  | `552` |  | `{`
| 132042 | `553` |  | `return forceZip64_;`
|  | `554` |  | `}`
|  | `555` |  | ``
|  | `556` |  | `/// <summary>`
|  | `557` |  | `/// Gets a value indicating if the entry requires Zip64 extensions`
|  | `558` |  | `/// to store the full entry values.`
|  | `559` |  | `/// </summary>`
|  | `560` |  | `/// <value>A <see cref="bool"/> value of true if a local header requires Zip64 extensions; false if not.</value>`
|  | `561` |  | `public bool LocalHeaderRequiresZip64 {`
|  | `562` |  | `get {`
| 395536 | `563` |  | `bool result = forceZip64_;`
|  | `564` |  | ``
| 395536 | `565` |  | `if (!result) {`
| 394651 | `566` |  | `ulong trueCompressedSize = compressedSize;`
|  | `567` |  | ``
| 394651 | `568` |  | `if ((versionToExtract == 0) && IsCrypted) {`
| 68 | `569` |  | `trueCompressedSize += ZipConstants.CryptoHeaderSize;`
|  | `570` |  | `}`
|  | `571` |  | ``
|  | `572` |  | `// TODO: A better estimation of the true limit based on compression overhead should be used`
|  | `573` |  | `// to determine when an entry should use Zip64.`
| 394651 | `574` |  | `result =`
| 394651 | `575` |  | `((this.size >= uint.MaxValue) || (trueCompressedSize >= uint.MaxValue)) &&`
| 394651 | `576` |  | `((versionToExtract == 0) || (versionToExtract >= ZipConstants.VersionZip64));`
|  | `577` |  | `}`
|  | `578` |  | ``
| 395536 | `579` |  | `return result;`
|  | `580` |  | `}`
|  | `581` |  | `}`
|  | `582` |  | ``
|  | `583` |  | `/// <summary>`
|  | `584` |  | `/// Get a value indicating wether the central directory entry requires Zip64 extensions to be stored.`
|  | `585` |  | `/// </summary>`
|  | `586` |  | `public bool CentralHeaderRequiresZip64 {`
|  | `587` |  | `get {`
| 197572 | `588` |  | `return LocalHeaderRequiresZip64 || (offset >= uint.MaxValue);`
|  | `589` |  | `}`
|  | `590` |  | `}`
|  | `591` |  | ``
|  | `592` |  | `/// <summary>`
|  | `593` |  | `/// Get/Set DosTime value.`
|  | `594` |  | `/// </summary>`
|  | `595` |  | `/// <remarks>`
|  | `596` |  | `/// The MS-DOS date format can only represent dates between 1/1/1980 and 12/31/2107.`
|  | `597` |  | `/// </remarks>`
|  | `598` |  | `public long DosTime {`
|  | `599` |  | `get {`
| 131812 | `600` |  | `if ((known & Known.Time) == 0) {`
| 0 | `601` |  | `return 0;`
|  | `602` |  | `} else {`
| 131812 | `603` |  | `return dosTime;`
|  | `604` |  | `}`
|  | `605` |  | `}`
|  | `606` |  | ``
|  | `607` |  | `set {`
|  | `608` |  | `unchecked {`
| 197925 | `609` |  | `dosTime = (uint)value;`
|  | `610` |  | `}`
|  | `611` |  | ``
| 197925 | `612` |  | `known |= Known.Time;`
| 197925 | `613` |  | `}`
|  | `614` |  | `}`
|  | `615` |  | ``
|  | `616` |  | `/// <summary>`
|  | `617` |  | `/// Gets/Sets the time of last modification of the entry.`
|  | `618` |  | `/// </summary>`
|  | `619` |  | `/// <remarks>`
|  | `620` |  | `/// The <see cref="DosTime"></see> property is updated to match this as far as possible.`
|  | `621` |  | `/// </remarks>`
|  | `622` |  | `public DateTime DateTime`
|  | `623` |  | `{`
| 2 | `624` |  | `get { return dateTime; }`
|  | `625` |  | ``
|  | `626` |  | `set {`
| 131886 | `627` |  | `var year = (uint)value.Year;`
| 131886 | `628` |  | `var month = (uint)value.Month;`
| 131886 | `629` |  | `var day = (uint)value.Day;`
| 131886 | `630` |  | `var hour = (uint)value.Hour;`
| 131886 | `631` |  | `var minute = (uint)value.Minute;`
| 131886 | `632` |  | `var second = (uint)value.Second;`
|  | `633` |  | ``
| 131886 | `634` |  | `if (year < 1980) {`
| 0 | `635` |  | `year = 1980;`
| 0 | `636` |  | `month = 1;`
| 0 | `637` |  | `day = 1;`
| 0 | `638` |  | `hour = 0;`
| 0 | `639` |  | `minute = 0;`
| 0 | `640` |  | `second = 0;`
| 131886 | `641` |  | `} else if (year > 2107) {`
| 0 | `642` |  | `year = 2107;`
| 0 | `643` |  | `month = 12;`
| 0 | `644` |  | `day = 31;`
| 0 | `645` |  | `hour = 23;`
| 0 | `646` |  | `minute = 59;`
| 0 | `647` |  | `second = 59;`
|  | `648` |  | `}`
|  | `649` |  | ``
| 131886 | `650` |  | `DosTime = ((year - 1980) & 0x7f) << 25 |`
| 131886 | `651` |  | `(month << 21) |`
| 131886 | `652` |  | `(day << 16) |`
| 131886 | `653` |  | `(hour << 11) |`
| 131886 | `654` |  | `(minute << 5) |`
| 131886 | `655` |  | `(second >> 1);`
| 131886 | `656` |  | `}`
|  | `657` |  | `}`
|  | `658` |  | ``
|  | `659` |  | `/// <summary>`
|  | `660` |  | `/// Returns the entry name.`
|  | `661` |  | `/// </summary>`
|  | `662` |  | `/// <remarks>`
|  | `663` |  | `/// The unix naming convention is followed.`
|  | `664` |  | `/// Path components in the entry should always separated by forward slashes ('/').`
|  | `665` |  | `/// Dos device names like C: should also be removed.`
|  | `666` |  | `/// See the <see cref="ZipNameTransform"/> class, or <see cref="CleanName(string)"/>`
|  | `667` |  | `///</remarks>`
|  | `668` |  | `public string Name {`
|  | `669` |  | `get {`
| 527086 | `670` |  | `return name;`
|  | `671` |  | `}`
|  | `672` |  | `}`
|  | `673` |  | ``
|  | `674` |  | `/// <summary>`
|  | `675` |  | `/// Gets/Sets the size of the uncompressed data.`
|  | `676` |  | `/// </summary>`
|  | `677` |  | `/// <returns>`
|  | `678` |  | `/// The size or -1 if unknown.`
|  | `679` |  | `/// </returns>`
|  | `680` |  | `/// <remarks>Setting the size before adding an entry to an archive can help`
|  | `681` |  | `/// avoid compatability problems with some archivers which dont understand Zip64 extensions.</remarks>`
|  | `682` |  | `public long Size {`
|  | `683` |  | `get {`
| 593205 | `684` |  | `return (known & Known.Size) != 0 ? (long)size : -1L;`
|  | `685` |  | `}`
|  | `686` |  | `set {`
| 131877 | `687` |  | `this.size = (ulong)value;`
| 131877 | `688` |  | `this.known |= Known.Size;`
| 131877 | `689` |  | `}`
|  | `690` |  | `}`
|  | `691` |  | ``
|  | `692` |  | `/// <summary>`
|  | `693` |  | `/// Gets/Sets the size of the compressed data.`
|  | `694` |  | `/// </summary>`
|  | `695` |  | `/// <returns>`
|  | `696` |  | `/// The compressed entry size or -1 if unknown.`
|  | `697` |  | `/// </returns>`
|  | `698` |  | `public long CompressedSize {`
|  | `699` |  | `get {`
| 462089 | `700` |  | `return (known & Known.CompressedSize) != 0 ? (long)compressedSize : -1L;`
|  | `701` |  | `}`
|  | `702` |  | `set {`
| 262984 | `703` |  | `this.compressedSize = (ulong)value;`
| 262984 | `704` |  | `this.known |= Known.CompressedSize;`
| 262984 | `705` |  | `}`
|  | `706` |  | `}`
|  | `707` |  | ``
|  | `708` |  | `/// <summary>`
|  | `709` |  | `/// Gets/Sets the crc of the uncompressed data.`
|  | `710` |  | `/// </summary>`
|  | `711` |  | `/// <exception cref="System.ArgumentOutOfRangeException">`
|  | `712` |  | `/// Crc is not in the range 0..0xffffffffL`
|  | `713` |  | `/// </exception>`
|  | `714` |  | `/// <returns>`
|  | `715` |  | `/// The crc value or -1 if unknown.`
|  | `716` |  | `/// </returns>`
|  | `717` |  | `public long Crc {`
|  | `718` |  | `get {`
| 329635 | `719` |  | `return (known & Known.Crc) != 0 ? crc & 0xffffffffL : -1L;`
|  | `720` |  | `}`
|  | `721` |  | `set {`
| 131852 | `722` |  | `if (((ulong)crc & 0xffffffff00000000L) != 0) {`
| 0 | `723` |  | `throw new ArgumentOutOfRangeException(nameof(value));`
|  | `724` |  | `}`
| 131852 | `725` |  | `this.crc = (uint)value;`
| 131852 | `726` |  | `this.known |= Known.Crc;`
| 131852 | `727` |  | `}`
|  | `728` |  | `}`
|  | `729` |  | ``
|  | `730` |  | `/// <summary>`
|  | `731` |  | `/// Gets/Sets the compression method. Only Deflated and Stored are supported.`
|  | `732` |  | `/// </summary>`
|  | `733` |  | `/// <returns>`
|  | `734` |  | `/// The compression method for this entry`
|  | `735` |  | `/// </returns>`
|  | `736` |  | `/// <see cref="ICSharpCode.SharpZipLib.Zip.CompressionMethod.Deflated"/>`
|  | `737` |  | `/// <see cref="ICSharpCode.SharpZipLib.Zip.CompressionMethod.Stored"/>`
|  | `738` |  | `public CompressionMethod CompressionMethod {`
|  | `739` |  | `get {`
| 461414 | `740` |  | `return method;`
|  | `741` |  | `}`
|  | `742` |  | ``
|  | `743` |  | `set {`
| 65837 | `744` |  | `if (!IsCompressionMethodSupported(value)) {`
| 1 | `745` |  | `throw new NotSupportedException("Compression method not supported");`
|  | `746` |  | `}`
| 65836 | `747` |  | `this.method = value;`
| 65836 | `748` |  | `}`
|  | `749` |  | `}`
|  | `750` |  | ``
|  | `751` |  | `/// <summary>`
|  | `752` |  | `/// Gets the compression method for outputting to the local or central header.`
|  | `753` |  | `/// Returns same value as CompressionMethod except when AES encrypting, which`
|  | `754` |  | `/// places 99 in the method and places the real method in the extra data.`
|  | `755` |  | `/// </summary>`
|  | `756` |  | `internal CompressionMethod CompressionMethodForHeader {`
|  | `757` |  | `get {`
| 257 | `758` |  | `return (AESKeySize > 0) ? CompressionMethod.WinZipAES : method;`
|  | `759` |  | `}`
|  | `760` |  | `}`
|  | `761` |  | ``
|  | `762` |  | `/// <summary>`
|  | `763` |  | `/// Gets/Sets the extra data.`
|  | `764` |  | `/// </summary>`
|  | `765` |  | `/// <exception cref="System.ArgumentOutOfRangeException">`
|  | `766` |  | `/// Extra data is longer than 64KB (0xffff) bytes.`
|  | `767` |  | `/// </exception>`
|  | `768` |  | `/// <returns>`
|  | `769` |  | `/// Extra data or null if not set.`
|  | `770` |  | `/// </returns>`
|  | `771` |  | `public byte[] ExtraData {`
|  | `772` |  | ``
|  | `773` |  | `get {`
|  | `774` |  | `// TODO: This is slightly safer but less efficient. Think about wether it should change.`
|  | `775` |  | `// return (byte[]) extra.Clone();`
| 263288 | `776` |  | `return extra;`
|  | `777` |  | `}`
|  | `778` |  | ``
|  | `779` |  | `set {`
| 65874 | `780` |  | `if (value == null) {`
| 0 | `781` |  | `extra = null;`
| 0 | `782` |  | `} else {`
| 65874 | `783` |  | `if (value.Length > 0xffff) {`
| 0 | `784` |  | `throw new System.ArgumentOutOfRangeException(nameof(value));`
|  | `785` |  | `}`
|  | `786` |  | ``
| 65874 | `787` |  | `extra = new byte[value.Length];`
| 65874 | `788` |  | `Array.Copy(value, 0, extra, 0, value.Length);`
|  | `789` |  | `}`
| 65874 | `790` |  | `}`
|  | `791` |  | `}`
|  | `792` |  | ``
|  | `793` |  | ``
|  | `794` |  | `/// <summary>`
|  | `795` |  | `/// For AES encrypted files returns or sets the number of bits of encryption (128, 192 or 256).`
|  | `796` |  | `/// When setting, only 0 (off), 128 or 256 is supported.`
|  | `797` |  | `/// </summary>`
|  | `798` |  | `public int AESKeySize {`
|  | `799` |  | `get {`
|  | `800` |  | `// the strength (1 or 3) is in the entry header`
| 132508 | `801` |  | `switch (_aesEncryptionStrength) {`
|  | `802` |  | `case 0:`
| 132508 | `803` |  | `return 0; // Not AES`
|  | `804` |  | `case 1:`
| 0 | `805` |  | `return 128;`
|  | `806` |  | `case 2:`
| 0 | `807` |  | `return 192; // Not used by WinZip`
|  | `808` |  | `case 3:`
| 0 | `809` |  | `return 256;`
|  | `810` |  | `default:`
| 0 | `811` |  | `throw new ZipException("Invalid AESEncryptionStrength " + _aesEncryptionStrength);`
|  | `812` |  | `}`
|  | `813` |  | `}`
|  | `814` |  | `set {`
| 0 | `815` |  | `switch (value) {`
|  | `816` |  | `case 0:`
| 0 | `817` |  | `_aesEncryptionStrength = 0;`
| 0 | `818` |  | `break;`
|  | `819` |  | `case 128:`
| 0 | `820` |  | `_aesEncryptionStrength = 1;`
| 0 | `821` |  | `break;`
|  | `822` |  | `case 256:`
| 0 | `823` |  | `_aesEncryptionStrength = 3;`
| 0 | `824` |  | `break;`
|  | `825` |  | `default:`
| 0 | `826` |  | `throw new ZipException("AESKeySize must be 0, 128 or 256: " + value);`
|  | `827` |  | `}`
|  | `828` |  | `}`
|  | `829` |  | `}`
|  | `830` |  | ``
|  | `831` |  | `/// <summary>`
|  | `832` |  | `/// AES Encryption strength for storage in extra data in entry header.`
|  | `833` |  | `/// 1 is 128 bit, 2 is 192 bit, 3 is 256 bit.`
|  | `834` |  | `/// </summary>`
|  | `835` |  | `internal byte AESEncryptionStrength {`
|  | `836` |  | `get {`
| 0 | `837` |  | `return (byte)_aesEncryptionStrength;`
|  | `838` |  | `}`
|  | `839` |  | `}`
|  | `840` |  | ``
|  | `841` |  | `/// <summary>`
|  | `842` |  | `/// Returns the length of the salt, in bytes`
|  | `843` |  | `/// </summary>`
|  | `844` |  | `internal int AESSaltLen {`
|  | `845` |  | `get {`
|  | `846` |  | `// Key size -> Salt length: 128 bits = 8 bytes, 192 bits = 12 bytes, 256 bits = 16 bytes.`
| 0 | `847` |  | `return AESKeySize / 16;`
|  | `848` |  | `}`
|  | `849` |  | `}`
|  | `850` |  | ``
|  | `851` |  | `/// <summary>`
|  | `852` |  | `/// Number of extra bytes required to hold the AES Header fields (Salt, Pwd verify, AuthCode)`
|  | `853` |  | `/// </summary>`
|  | `854` |  | `internal int AESOverheadSize {`
|  | `855` |  | `get {`
|  | `856` |  | `// File format:`
|  | `857` |  | `// Bytes Content`
|  | `858` |  | `// Variable Salt value`
|  | `859` |  | `// 2 Password verification value`
|  | `860` |  | `// Variable Encrypted file data`
|  | `861` |  | `// 10 Authentication code`
| 0 | `862` |  | `return 12 + AESSaltLen;`
|  | `863` |  | `}`
|  | `864` |  | `}`
|  | `865` |  | ``
|  | `866` |  | `/// <summary>`
|  | `867` |  | `/// Process extra data fields updating the entry based on the contents.`
|  | `868` |  | `/// </summary>`
|  | `869` |  | `/// <param name="localHeader">True if the extra data fields should be handled`
|  | `870` |  | `/// for a local header, rather than for a central header.`
|  | `871` |  | `/// </param>`
|  | `872` |  | `internal void ProcessExtraData(bool localHeader)`
|  | `873` |  | `{`
| 66037 | `874` |  | `var extraData = new ZipExtraData(this.extra);`
|  | `875` |  | ``
| 66037 | `876` |  | `if (extraData.Find(0x0001)) {`
|  | `877` |  | `// Version required to extract is ignored here as some archivers dont set it correctly`
|  | `878` |  | `// in theory it should be version 45 or higher`
|  | `879` |  | ``
|  | `880` |  | `// The recorded size will change but remember that this is zip64.`
| 123 | `881` |  | `forceZip64_ = true;`
|  | `882` |  | ``
| 123 | `883` |  | `if (extraData.ValueLength < 4) {`
| 0 | `884` |  | `throw new ZipException("Extra data extended Zip64 information length is invalid");`
|  | `885` |  | `}`
|  | `886` |  | ``
|  | `887` |  | `// (localHeader ||) was deleted, because actually there is no specific difference with reading sizes between loc`
|  | `888` |  | `// https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT`
|  | `889` |  | `// ...`
|  | `890` |  | `// 4.4 Explanation of fields`
|  | `891` |  | `// ...`
|  | `892` |  | `// 4.4.8 compressed size: (4 bytes)`
|  | `893` |  | `// 4.4.9 uncompressed size: (4 bytes)`
|  | `894` |  | `//`
|  | `895` |  | `// The size of the file compressed (4.4.8) and uncompressed,`
|  | `896` |  | `// (4.4.9) respectively. When a decryption header is present it`
|  | `897` |  | `// will be placed in front of the file data and the value of the`
|  | `898` |  | `// compressed file size will include the bytes of the decryption`
|  | `899` |  | `// header. If bit 3 of the general purpose bit flag is set,`
|  | `900` |  | `// these fields are set to zero in the local header and the`
|  | `901` |  | `// correct values are put in the data descriptor and`
|  | `902` |  | `// in the central directory. If an archive is in ZIP64 format`
|  | `903` |  | `// and the value in this field is 0xFFFFFFFF, the size will be`
|  | `904` |  | `// in the corresponding 8 byte ZIP64 extended information`
|  | `905` |  | `// extra field. When encrypting the central directory, if the`
|  | `906` |  | `// local header is not in ZIP64 format and general purpose bit`
|  | `907` |  | `// flag 13 is set indicating masking, the value stored for the`
|  | `908` |  | `// uncompressed size in the Local Header will be zero.`
|  | `909` |  | `//`
|  | `910` |  | `// Othewise there is problem with minizip implementation`
| 123 | `911` |  | `if (size == uint.MaxValue) {`
| 123 | `912` |  | `size = (ulong)extraData.ReadLong();`
|  | `913` |  | `}`
|  | `914` |  | ``
| 123 | `915` |  | `if (compressedSize == uint.MaxValue) {`
| 123 | `916` |  | `compressedSize = (ulong)extraData.ReadLong();`
|  | `917` |  | `}`
|  | `918` |  | ``
| 123 | `919` |  | `if (!localHeader && (offset == uint.MaxValue)) {`
| 0 | `920` |  | `offset = extraData.ReadLong();`
|  | `921` |  | `}`
|  | `922` |  | ``
|  | `923` |  | `// Disk number on which file starts is ignored`
| 0 | `924` |  | `} else {`
| 65914 | `925` |  | `if (`
| 65914 | `926` |  | `((versionToExtract & 0xff) >= ZipConstants.VersionZip64) &&`
| 65914 | `927` |  | `((size == uint.MaxValue) || (compressedSize == uint.MaxValue))`
| 65914 | `928` |  | `) {`
| 0 | `929` |  | `throw new ZipException("Zip64 Extended information required but is missing.");`
|  | `930` |  | `}`
|  | `931` |  | `}`
|  | `932` |  | ``
| 66037 | `933` |  | `dateTime = GetDateTime(extraData);`
| 66037 | `934` |  | `if (method == CompressionMethod.WinZipAES) {`
| 0 | `935` |  | `ProcessAESExtraData(extraData);`
|  | `936` |  | `}`
| 66037 | `937` |  | `}`
|  | `938` |  | ``
|  | `939` |  | `private DateTime GetDateTime(ZipExtraData extraData) {`
|  | `940` |  | `// Check for NT timestamp`
|  | `941` |  | `// NOTE: Disable by default to match behavior of InfoZIP`
|  | `942` |  | `#if RESPECT_NT_TIMESTAMP`
|  | `943` |  | `NTTaggedData ntData = extraData.GetData<NTTaggedData>();`
|  | `944` |  | `if (ntData != null)`
|  | `945` |  | `return ntData.LastModificationTime;`
|  | `946` |  | `#endif`
|  | `947` |  | ``
|  | `948` |  | `// Check for Unix timestamp`
| 66037 | `949` |  | `ExtendedUnixData unixData = extraData.GetData<ExtendedUnixData>();`
| 66037 | `950` |  | `if (unixData != null &&`
| 66037 | `951` |  | `// Only apply modification time, but require all other values to be present`
| 66037 | `952` |  | `// This is done to match InfoZIP's behaviour`
| 66037 | `953` |  | `((unixData.Include & ExtendedUnixData.Flags.ModificationTime) != 0) &&`
| 66037 | `954` |  | `((unixData.Include & ExtendedUnixData.Flags.AccessTime) != 0) &&`
| 66037 | `955` |  | `((unixData.Include & ExtendedUnixData.Flags.CreateTime) != 0))`
| 0 | `956` |  | `return unixData.ModificationTime;`
|  | `957` |  | ``
|  | `958` |  | `// Fall back to DOS time`
| 66037 | `959` |  | `uint sec = Math.Min(59, 2 * (dosTime & 0x1f));`
| 66037 | `960` |  | `uint min = Math.Min(59, (dosTime >> 5) & 0x3f);`
| 66037 | `961` |  | `uint hrs = Math.Min(23, (dosTime >> 11) & 0x1f);`
| 66037 | `962` |  | `uint mon = Math.Max(1, Math.Min(12, ((dosTime >> 21) & 0xf)));`
| 66037 | `963` |  | `uint year = ((dosTime >> 25) & 0x7f) + 1980;`
| 66037 | `964` |  | `int day = Math.Max(1, Math.Min(DateTime.DaysInMonth((int)year, (int)mon), (int)((dosTime >> 16) & 0x1f)));`
| 66037 | `965` |  | `return new DateTime((int)year, (int)mon, day, (int)hrs, (int)min, (int)sec, DateTimeKind.Utc);`
|  | `966` |  | `}`
|  | `967` |  | ``
|  | `968` |  | `// For AES the method in the entry is 99, and the real compression method is in the extradata`
|  | `969` |  | `//`
|  | `970` |  | `private void ProcessAESExtraData(ZipExtraData extraData)`
|  | `971` |  | `{`
|  | `972` |  | ``
| 0 | `973` |  | `if (extraData.Find(0x9901)) {`
|  | `974` |  | `// Set version and flag for Zipfile.CreateAndInitDecryptionStream`
| 0 | `975` |  | `versionToExtract = ZipConstants.VERSION_AES; // Ver 5.1 = AES see "Version" getter`
|  | `976` |  | `// Set StrongEncryption flag for ZipFile.CreateAndInitDecryptionStream`
| 0 | `977` |  | `Flags = Flags | (int)GeneralBitFlags.StrongEncryption;`
|  | `978` |  | `//`
|  | `979` |  | `// Unpack AES extra data field see http://www.winzip.com/aes_info.htm`
| 0 | `980` |  | `int length = extraData.ValueLength; // Data size currently 7`
| 0 | `981` |  | `if (length < 7)`
| 0 | `982` |  | `throw new ZipException("AES Extra Data Length " + length + " invalid.");`
| 0 | `983` |  | `int ver = extraData.ReadShort(); // Version number (1=AE-1 2=AE-2)`
| 0 | `984` |  | `int vendorId = extraData.ReadShort(); // 2-character vendor ID 0x4541 = "AE"`
| 0 | `985` |  | `int encrStrength = extraData.ReadByte(); // encryption strength 1 = 128 2 = 192 3 = 256`
| 0 | `986` |  | `int actualCompress = extraData.ReadShort(); // The actual compression method used to compress the file`
| 0 | `987` |  | `_aesVer = ver;`
| 0 | `988` |  | `_aesEncryptionStrength = encrStrength;`
| 0 | `989` |  | `method = (CompressionMethod)actualCompress;`
| 0 | `990` |  | `} else`
| 0 | `991` |  | `throw new ZipException("AES Extra Data missing");`
|  | `992` |  | `}`
|  | `993` |  | ``
|  | `994` |  | `/// <summary>`
|  | `995` |  | `/// Gets/Sets the entry comment.`
|  | `996` |  | `/// </summary>`
|  | `997` |  | `/// <exception cref="System.ArgumentOutOfRangeException">`
|  | `998` |  | `/// If comment is longer than 0xffff.`
|  | `999` |  | `/// </exception>`
|  | `1000` |  | `/// <returns>`
|  | `1001` |  | `/// The comment or null if not set.`
|  | `1002` |  | `/// </returns>`
|  | `1003` |  | `/// <remarks>`
|  | `1004` |  | `/// A comment is only available for entries when read via the <see cref="ZipFile"/> class.`
|  | `1005` |  | `/// The <see cref="ZipInputStream"/> class doesnt have the comment data available.`
|  | `1006` |  | `/// </remarks>`
|  | `1007` |  | `public string Comment {`
|  | `1008` |  | `get {`
| 131673 | `1009` |  | `return comment;`
|  | `1010` |  | `}`
|  | `1011` |  | `set {`
|  | `1012` |  | `// This test is strictly incorrect as the length is in characters`
|  | `1013` |  | `// while the storage limit is in bytes.`
|  | `1014` |  | `// While the test is partially correct in that a comment of this length or greater`
|  | `1015` |  | `// is definitely invalid, shorter comments may also have an invalid length`
|  | `1016` |  | `// where there are multi-byte characters`
|  | `1017` |  | `// The full test is not possible here however as the code page to apply conversions with`
|  | `1018` |  | `// isnt available.`
| 3 | `1019` |  | `if ((value != null) && (value.Length > 0xffff)) {`
| 0 | `1020` |  | `throw new ArgumentOutOfRangeException(nameof(value), "cannot exceed 65535");`
|  | `1021` |  | `}`
|  | `1022` |  | ``
| 3 | `1023` |  | `comment = value;`
| 3 | `1024` |  | `}`
|  | `1025` |  | `}`
|  | `1026` |  | ``
|  | `1027` |  | `/// <summary>`
|  | `1028` |  | `/// Gets a value indicating if the entry is a directory.`
|  | `1029` |  | `/// however.`
|  | `1030` |  | `/// </summary>`
|  | `1031` |  | `/// <remarks>`
|  | `1032` |  | `/// A directory is determined by an entry name with a trailing slash '/'.`
|  | `1033` |  | `/// The external file attributes can also indicate an entry is for a directory.`
|  | `1034` |  | `/// Currently only dos/windows attributes are tested in this manner.`
|  | `1035` |  | `/// The trailing slash convention should always be followed.`
|  | `1036` |  | `/// </remarks>`
|  | `1037` |  | `public bool IsDirectory {`
|  | `1038` |  | `get {`
| 526334 | `1039` |  | `int nameLength = name.Length;`
| 526334 | `1040` |  | `bool result =`
| 526334 | `1041` |  | `((nameLength > 0) &&`
| 526334 | `1042` |  | `((name[nameLength - 1] == '/') || (name[nameLength - 1] == '\\'))) ||`
| 526334 | `1043` |  | `HasDosAttributes(16)`
| 526334 | `1044` |  | `;`
| 27 | `1045` |  | `return result;`
|  | `1046` |  | `}`
|  | `1047` |  | `}`
|  | `1048` |  | ``
|  | `1049` |  | `/// <summary>`
|  | `1050` |  | `/// Get a value of true if the entry appears to be a file; false otherwise`
|  | `1051` |  | `/// </summary>`
|  | `1052` |  | `/// <remarks>`
|  | `1053` |  | `/// This only takes account of DOS/Windows attributes. Other operating systems are ignored.`
|  | `1054` |  | `/// For linux and others the result may be incorrect.`
|  | `1055` |  | `/// </remarks>`
|  | `1056` |  | `public bool IsFile {`
|  | `1057` |  | `get {`
| 263486 | `1058` |  | `return !IsDirectory && !HasDosAttributes(8);`
|  | `1059` |  | `}`
|  | `1060` |  | `}`
|  | `1061` |  | ``
|  | `1062` |  | `/// <summary>`
|  | `1063` |  | `/// Test entry to see if data can be extracted.`
|  | `1064` |  | `/// </summary>`
|  | `1065` |  | `/// <returns>Returns true if data can be extracted for this entry; false otherwise.</returns>`
|  | `1066` |  | `public bool IsCompressionMethodSupported()`
|  | `1067` |  | `{`
| 132012 | `1068` |  | `return IsCompressionMethodSupported(CompressionMethod);`
|  | `1069` |  | `}`
|  | `1070` |  | ``
|  | `1071` |  | `#region ICloneable Members`
|  | `1072` |  | `/// <summary>`
|  | `1073` |  | `/// Creates a copy of this zip entry.`
|  | `1074` |  | `/// </summary>`
|  | `1075` |  | `/// <returns>An <see cref="Object"/> that is a copy of the current instance.</returns>`
|  | `1076` |  | `public object Clone()`
|  | `1077` |  | `{`
| 461093 | `1078` |  | `var result = (ZipEntry)this.MemberwiseClone();`
|  | `1079` |  | ``
|  | `1080` |  | `// Ensure extra data is unique if it exists.`
| 461093 | `1081` |  | `if (extra != null) {`
| 72 | `1082` |  | `result.extra = new byte[extra.Length];`
| 72 | `1083` |  | `Array.Copy(extra, 0, result.extra, 0, extra.Length);`
|  | `1084` |  | `}`
|  | `1085` |  | ``
| 461093 | `1086` |  | `return result;`
|  | `1087` |  | `}`
|  | `1088` |  | ``
|  | `1089` |  | `#endregion`
|  | `1090` |  | ``
|  | `1091` |  | `/// <summary>`
|  | `1092` |  | `/// Gets a string representation of this ZipEntry.`
|  | `1093` |  | `/// </summary>`
|  | `1094` |  | `/// <returns>A readable textual representation of this <see cref="ZipEntry"/></returns>`
|  | `1095` |  | `public override string ToString()`
|  | `1096` |  | `{`
| 0 | `1097` |  | `return name;`
|  | `1098` |  | `}`
|  | `1099` |  | ``
|  | `1100` |  | `/// <summary>`
|  | `1101` |  | `/// Test a <see cref="CompressionMethod">compression method</see> to see if this library`
|  | `1102` |  | `/// supports extracting data compressed with that method`
|  | `1103` |  | `/// </summary>`
|  | `1104` |  | `/// <param name="method">The compression method to test.</param>`
|  | `1105` |  | `/// <returns>Returns true if the compression method is supported; false otherwise</returns>`
|  | `1106` |  | `public static bool IsCompressionMethodSupported(CompressionMethod method)`
|  | `1107` |  | `{`
| 197849 | `1108` |  | `return`
| 197849 | `1109` |  | `(method == CompressionMethod.Deflated) ||`
| 197849 | `1110` |  | `(method == CompressionMethod.Stored);`
|  | `1111` |  | `}`
|  | `1112` |  | ``
|  | `1113` |  | `/// <summary>`
|  | `1114` |  | `/// Cleans a name making it conform to Zip file conventions.`
|  | `1115` |  | `/// Devices names ('c:\') and UNC share names ('\\server\share') are removed`
|  | `1116` |  | `/// and forward slashes ('\') are converted to back slashes ('/').`
|  | `1117` |  | `/// Names are made relative by trimming leading slashes which is compatible`
|  | `1118` |  | `/// with the ZIP naming convention.`
|  | `1119` |  | `/// </summary>`
|  | `1120` |  | `/// <param name="name">The name to clean</param>`
|  | `1121` |  | `/// <returns>The 'cleaned' name.</returns>`
|  | `1122` |  | `/// <remarks>`
|  | `1123` |  | `/// The <seealso cref="ZipNameTransform">Zip name transform</seealso> class is more flexible.`
|  | `1124` |  | `/// </remarks>`
|  | `1125` |  | `public static string CleanName(string name)`
|  | `1126` |  | `{`
| 131877 | `1127` |  | `if (name == null) {`
| 0 | `1128` |  | `return string.Empty;`
|  | `1129` |  | `}`
|  | `1130` |  | ``
| 131877 | `1131` |  | `if (Path.IsPathRooted(name)) {`
|  | `1132` |  | `// NOTE:`
|  | `1133` |  | `// for UNC names... \\machine\share\zoom\beet.txt gives \zoom\beet.txt`
| 0 | `1134` |  | `name = name.Substring(Path.GetPathRoot(name).Length);`
|  | `1135` |  | `}`
|  | `1136` |  | ``
| 131877 | `1137` |  | `name = name.Replace(@"\", "/");`
|  | `1138` |  | ``
| 131877 | `1139` |  | `while ((name.Length > 0) && (name[0] == '/')) {`
| 0 | `1140` |  | `name = name.Remove(0, 1);`
|  | `1141` |  | `}`
| 131877 | `1142` |  | `return name;`
|  | `1143` |  | `}`
|  | `1144` |  | ``
|  | `1145` |  | `#region Instance Fields`
|  | `1146` |  | `Known known;`
| 131879 | `1147` |  | `int externalFileAttributes = -1; // contains external attributes (O/S dependant)`
|  | `1148` |  | ``
|  | `1149` |  | `ushort versionMadeBy; // Contains host system and version information`
|  | `1150` |  | `// only relevant for central header entries`
|  | `1151` |  | ``
|  | `1152` |  | `string name;`
|  | `1153` |  | `ulong size;`
|  | `1154` |  | `ulong compressedSize;`
|  | `1155` |  | `ushort versionToExtract; // Version required to extract (library handles <= 2.0)`
|  | `1156` |  | `uint crc;`
|  | `1157` |  | `uint dosTime;`
|  | `1158` |  | `DateTime dateTime;`
|  | `1159` |  | ``
| 131879 | `1160` |  | `CompressionMethod method = CompressionMethod.Deflated;`
|  | `1161` |  | `byte[] extra;`
|  | `1162` |  | `string comment;`
|  | `1163` |  | ``
|  | `1164` |  | `int flags; // general purpose bit flags`
|  | `1165` |  | ``
| 131879 | `1166` |  | `long zipFileIndex = -1; // used by ZipFile`
|  | `1167` |  | `long offset; // used by ZipFile and ZipOutputStream`
|  | `1168` |  | ``
|  | `1169` |  | `bool forceZip64_;`
|  | `1170` |  | `byte cryptoCheckValue_;`
|  | `1171` |  | `int _aesVer; // Version number (2 = AE-2 ?). Assigned but not used.`
|  | `1172` |  | `int _aesEncryptionStrength; // Encryption strength 1 = 128 2 = 192 3 = 256`
|  | `1173` |  | `#endregion`
|  | `1174` |  | `}`
|  | `1175` |  | `}`