From d4f98751aba7e80346b8c2571c813c4a4ca6e294 Mon Sep 17 00:00:00 2001 From: p1ksel Date: Wed, 5 Aug 2020 17:13:38 +0200 Subject: [PATCH 1/5] Enable nullable ref types and fix warnings --- docs/sharpziplib-nuget-256x256.png | Bin 0 -> 5435 bytes .../ICSharpCode.SharpZipLib.csproj | 8 +++++++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 docs/sharpziplib-nuget-256x256.png diff --git a/docs/sharpziplib-nuget-256x256.png b/docs/sharpziplib-nuget-256x256.png new file mode 100644 index 0000000000000000000000000000000000000000..60b3a8dae4021d51356ffcb25261306cc14afa58 GIT binary patch literal 5435 zcmX|Fc|6o#_rIT+VFuaPEE&5ZDr9FY*|!*xeI2r|MYf5`k~PYjr3l$0OR^P7z9hSd ziLa0~+l+O7p67YJet(^F?z#88&OPsY&pG$Tn;2=+Qgc!R0BCh}G))13&R7VbD9?yZ zKpF0goDaHT8D!>*3%chR;0n}Se4Sj;y55d%uBNVzE}{N?u1Wx~{M6M{!-o7=dtsQ! z-NV`&rX4n~;YCMz)XlLKFIXuVAMMAXulbf$a6B0gPgCj_N0~UC7ljd3n>FbYudyDUFgVOH-;}V_wfEkO)S`MEr}3oq5x_?l5@D@H zu!zP^@r{IJrdX-3@(pH=mcKUmL9GhmD5j0kp>~P!(Jf;ZQ#JQMA|u{%Czxt?dSoI` zgJzS{AECdpn!$wlLyf|exE&~8+Hz~**SI4VyQQ!JpfdHL{;hlofe^;${R2R9ICC&*-#Bq_N2yI0SeN{t4J`?et| zSh0ElhH*-~)>h~``zNCt1p=fZ`tvkPqmyw7?%env#R7LbxFHejtx4h*%w%i*O- z1x9m5%*UzFd4bZgtS$&~fwZ@~9-^K`zx%T@+&m0RRCktaQ7*#mJ1XpXxR)yy!4xOpgKSBIb?D@LW`07?2V_6fA6DtOUCh2`o!|UTV~uFs8byf>IVMHtCy) z@GJt-?{i{;+7TUoiWlw0ZZZm8If5fLU=7@$UKK-YW`$~XTAMhzv0S zlX;8aX8ef~9saATLB43@e)_-h+PupNoy9fj6N=@i54(S0?1LX@CfyV$+z&~)J|}+% zoXJNAHSN0X$A4DU3;60MU$0(IJjwZ{vMIuP zeV6%Knc(P+ykhaF!l6IMzL~_MK?iMBvzcgu{ca_l##7PKk!HWNU$;_UDs!buKK688 zBPXWp+iL?Oa=%gQ%9M^7zTQ5F0d$Pu&+{M&RVN*PzKV%c4NyKdrc^naN!-${dfW!x z9l`s<{4#4g2A*?Wx6U>XP)yQ6)&%{{b~yNyLNyl9tgj6?uP!~S)LznuT<+O_pNjf5 z(A1K(IP^sb{4s%iQ%>IZeYEnQ-CLdvoN%M>uyL2lSc9XXCZ@>FJ!TpYMG{Y zqn56+oqW8Je06Q%^Ol~b)P#57%tGUHPRQmx-tl7RWr@hQ;=Mjq)R=Y_LO5rZLhIP} zYhaptrA2H|=613i*WLLVx;eY%tkztU>U-IWNJDO+CB9Xsu%BrT<%T3*r%)=BC2{%M z^!^kpwX`E4;sA>&d+N9T->}ubCmpITRcP^f!6PM?rqbe!;cXuGkqNyV*l{5-HnjLB2Oz_abiR998wf(S{-N@HFkEx3sExDYdIVY})6fd`znIQCFJv8yC?>TY z|I*eXYGlOi!bgu%&hZ*RxbugEgbKK#sUbqmE`Y7Lm}XP_q@?xjuY;8#riDz3!pCP_ zi?)X){V7i6V71_M(lA9yWx~NQaYC4t3ZUKea$jrLv~45p>E+v8^8f*WbG23)Eu}}5 zh;PY?ysO~Pi~zCD|Dksh|$4ll1hgYCZsFTy+ z#V&j{zS9KhmsC;kyT`)*RpzXei*ndZqutap^U+9ZaN44JZ~wzg=ZGIjW%NL~orVz<_tE*A%I~I25#HS*~V*0yJvUZE@TB<))d(V0OQRxIH(z4(!y_ zNq2DEh-w2RK{<~?j$h_lgOpE3RqWnNNp*B@Hmkp$DRL6G-1qf;5C!_-1uzKX zPM(Zpeu2Ba9ciiBwS3{>kA>^nu%RahR-y;0Zcw#$fX>C^G-9j9Lo-c`B7<-6Z-9%| zhrBFzOwK&MJ*W9S<-=SeYFTAeGq0*&sLO#HoUP)KHdZ+-Olxq@9tlm_8vILa;2C9; z&3!a32gsfv-ztzDw$=TLo}=%mwWsn^-i#-VD$x_!1^8-UO$Rk6xnQwQBn~Xd~IuGJwr9;U8Db%N5{wM zjX_@*Ugd|LF3wbUyUdbVLOWz6Y>tyTG2_t2-x0IKgqyPwb5D126=aR>kHRBTg|N4Q zx^k#?tfBnFL6=#{4d-7;O&p617PM%rCW~v^Tq0}Rr0q6*nz%)c0J|YL^1|ml#?TI~ zMt2FJR=p7hV9YS>`{&;?#4rG+ewUc-vCp@Oc=9?YqIlrm?HvsDl}~H~JQWi3&)2Ci)BDKY(M*-KdoojN zpVDUAiv#bAf#eGkBS{B7Vq4qs&SGZ`eB{!x6j0-oFt2T z6!6mzJ;{^8`elm@~)=%U=NHALi~5~DMIWP#PJ`-ta-++{})htW2J3O zkyEt*Bqw74ZoRppc$7t->va~n8lx@!t{>kcK5(y&s7!!xWty$<gLleqEsZxkQyy3GLEgdYfpxKjqwukzNY*dOMsdqWa(CwR!j2Q;~y>56-P=3dx_Q zq6{nT+3<_Zy$X$C&~Z!4;@Yn>KRyY37^waGgZAfnC7OEGQ^$K=U-UA{=e;-W6!K15 z>s0=MP*uBQTZ_0pTG9TT8h=h9ahV*i{gnYsO53LNH`iFdI_u87n_3Bk_LplVxjHAZT6qT9b zI55$g7=A}9w|*b(Hn^$3MgL@dh0$J`Yrf}mPK;zw=HYC}bW@<@H7firm8>nfxH12^ zhi5tCyqbaxkK|s`JeCdGdP$c`yiF+LD24!Q1345y5S?H~izah2 zgE8%y`5YKR%@e!XQ4MFXTY7&c{I(nr2jwrtg?ABvG?FAO=|A z(D85gJFr4(nq~lu-N=@BITe z2$`F%`{ev0W6H0e8hKic`C(uXM_zwFCthbSwWVP~15keZl2|xL8HIR&B&d9ADM*wR z1`&GQMruH@GAm$K3xV0=t-p!tq|@HnKh9hS4+W@VV__MF+C5hD&p>g4V518!5m|`c zFSnFZ|K-}LX32&SO;YcVjLEX1?tQL#pU(H3AwJ}MEJ(d;|I zT#?ixb%$1lOfWO+QFzYZ>qd0v8rf#?A2U z*h1$cb_6QU)>Yy_o*f9msvg?LfS5HY|BopXGWZAgJJk=z|80i{r4Zk?n~o<%SilN3 z@h{Qc$?smyU4hEvPZvx2%Rh18Eo1C^@KSlyc#j|lSKw4UjdpuA)oTrz@DG`(X#ywe z({+zEk()G_0@RSixwZc;XT=V$}h1|t;_2FU`>`gV&_Vk&I;2}b$$PwgQG8x2aU zOC&|}Q=wOkcojYe4Mt7nRqdN_4l^!G({~SUd{#JDTNZFq_DAccJRXuAGIGj}Id zE^StLq@}Ppyk$_ztK6qeW$Sh$y4sR;D%k-y*58hzp1DLZap<95w=DqxM2(`y@aaQW59`FRhLDrC80TC z0wee$jFQqrX>wFsL=#%g+{^K*ucF%xdoDoufQLoZb`yeg>>ONdFr}MaC#tM#JTM*z zkRPgRI@S)!r6<}YEmH)liecx)BmiI#A+tLGE4J0y2ayvCXTPC9_lA*XwYo#}{{ai% B_~ZZp literal 0 HcmV?d00001 diff --git a/src/ICSharpCode.SharpZipLib/ICSharpCode.SharpZipLib.csproj b/src/ICSharpCode.SharpZipLib/ICSharpCode.SharpZipLib.csproj index ea7bdf756..f08b18c1d 100644 --- a/src/ICSharpCode.SharpZipLib/ICSharpCode.SharpZipLib.csproj +++ b/src/ICSharpCode.SharpZipLib/ICSharpCode.SharpZipLib.csproj @@ -7,6 +7,8 @@ true true $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + 8.0 + Enable @@ -20,7 +22,7 @@ SharpZipLib (#ziplib, formerly NZipLib) is a compression library for Zip, GZip, BZip2, and Tar written entirely in C# for .NET. It is implemented as an assembly (installable in the GAC), and thus can easily be incorporated into other projects (in any .NET language) MIT http://icsharpcode.github.io/SharpZipLib/ - http://icsharpcode.github.io/SharpZipLib/assets/sharpziplib-nuget-256x256.png + icon.png https://github.com/icsharpcode/SharpZipLib Copyright © 2000-2019 SharpZipLib Contributors Compression Library Zip GZip BZip2 LZW Tar @@ -34,4 +36,8 @@ Please see https://github.com/icsharpcode/SharpZipLib/wiki/Release-1.2 for more + + + + From 6a1ca5ea2286c21b84cd7421d85850d4053156aa Mon Sep 17 00:00:00 2001 From: p1ksel Date: Thu, 6 Aug 2020 01:55:34 +0200 Subject: [PATCH 2/5] Enforce nullable reference type declaration/checking --- .../BZip2/BZip2Exception.cs | 6 +- .../BZip2/BZip2InputStream.cs | 21 +- .../BZip2/BZip2OutputStream.cs | 21 +- src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs | 22 + .../Core/Exceptions/SharpZipBaseException.cs | 6 +- .../Exceptions/StreamDecodingException.cs | 6 +- .../Exceptions/StreamUnsupportedException.cs | 6 +- .../UnexpectedEndOfStreamException.cs | 6 +- .../Exceptions/ValueOutOfRangeException.cs | 10 +- .../Core/FileSystemScanner.cs | 345 ++++----------- .../Core/INameTransform.cs | 4 +- .../Core/IScanFilter.cs | 2 +- .../Core/InvalidNameException.cs | 6 +- .../Core/NameFilter.cs | 16 +- .../Core/PathFilter.cs | 16 +- .../Core/StreamUtils.cs | 4 +- .../Encryption/PkzipClassic.cs | 54 ++- .../Encryption/ZipAESStream.cs | 28 +- .../Encryption/ZipAESTransform.cs | 10 +- src/ICSharpCode.SharpZipLib/GZip/GZip.cs | 4 +- .../GZip/GZipException.cs | 6 +- .../GZip/GzipInputStream.cs | 4 +- .../Lzw/LzwException.cs | 6 +- .../Lzw/LzwInputStream.cs | 14 +- .../Tar/InvalidHeaderException.cs | 6 +- src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs | 123 +++--- src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs | 6 +- src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs | 96 +---- .../Tar/TarException.cs | 6 +- .../Tar/TarExtendedHeaderReader.cs | 63 ++- src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs | 238 +++-------- .../Tar/TarInputStream.cs | 32 +- .../Tar/TarOutputStream.cs | 8 +- .../Zip/Compression/Deflater.cs | 4 +- .../Zip/Compression/DeflaterEngine.cs | 8 +- .../Zip/Compression/DeflaterHuffman.cs | 13 +- .../Zip/Compression/Inflater.cs | 20 +- .../Zip/Compression/InflaterDynHeader.cs | 4 +- .../Zip/Compression/InflaterHuffmanTree.cs | 8 +- .../Zip/Compression/PendingBuffer.cs | 4 +- .../Streams/DeflaterOutputStream.cs | 18 +- .../Streams/InflaterInputStream.cs | 12 +- .../Zip/Compression/Streams/OutputWindow.cs | 2 +- .../Compression/Streams/StreamManipulator.cs | 3 +- src/ICSharpCode.SharpZipLib/Zip/FastZip.cs | 252 +++++------ .../Zip/IEntryFactory.cs | 10 +- .../Zip/WindowsNameTransform.cs | 12 +- .../Zip/ZipConstants.cs | 14 +- src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs | 16 +- .../Zip/ZipEntryFactory.cs | 14 +- .../Zip/ZipException.cs | 6 +- .../Zip/ZipExtraData.cs | 80 ++-- src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs | 401 ++++++++---------- .../Zip/ZipHelperStream.cs | 64 +-- .../Zip/ZipInputStream.cs | 23 +- .../Zip/ZipNameTransform.cs | 46 +- .../Zip/ZipOutputStream.cs | 8 +- src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs | 12 +- 58 files changed, 884 insertions(+), 1371 deletions(-) create mode 100644 src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs index 111d21cdc..451ccc004 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs @@ -20,7 +20,7 @@ public BZip2Exception() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public BZip2Exception(string message) + public BZip2Exception(string? message) : base(message) { } @@ -30,7 +30,7 @@ public BZip2Exception(string message) /// /// A that describes the error. /// The that caused this exception. - public BZip2Exception(string message, Exception innerException) + public BZip2Exception(string? message, Exception? innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public BZip2Exception(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected BZip2Exception(SerializationInfo info, StreamingContext context) + protected BZip2Exception(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs index e639bc1f5..f4b704323 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs @@ -1,6 +1,7 @@ using ICSharpCode.SharpZipLib.Checksum; using System; using System.IO; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.BZip2 { @@ -9,7 +10,7 @@ namespace ICSharpCode.SharpZipLib.BZip2 /// public class BZip2InputStream : Stream { - #region Constants +#region Constants private const int START_BLOCK_STATE = 1; private const int RAND_PART_A_STATE = 2; @@ -19,9 +20,9 @@ public class BZip2InputStream : Stream private const int NO_RAND_PART_B_STATE = 6; private const int NO_RAND_PART_C_STATE = 7; - #endregion Constants +#endregion Constants - #region Instance Fields +#region Instance Fields /*-- index of the last char in the block, so @@ -55,8 +56,8 @@ The current block size is 100000 * this number. private byte[] selector = new byte[BZip2Constants.MaximumSelectors]; private byte[] selectorMtf = new byte[BZip2Constants.MaximumSelectors]; - private int[] tt; - private byte[] ll8; + private int[] tt = EmptyRefs.Int32Array; + private byte[] ll8 = EmptyRefs.ByteArray; /*-- freq table collected to save a pass over the data @@ -87,7 +88,7 @@ during decompression. private int i2, j2; private byte z; - #endregion Instance Fields +#endregion Instance Fields /// /// Construct instance for reading from stream @@ -119,7 +120,7 @@ public BZip2InputStream(Stream stream) /// public bool IsStreamOwner { get; set; } = true; - #region Stream Overrides +#region Stream Overrides /// /// Gets a value indicating if the stream supports reading @@ -222,7 +223,7 @@ public override void SetLength(long value) /// The offset to start obtaining data from. /// The number of bytes of data to write. /// Any access - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { throw new NotSupportedException("BZip2InputStream Write not supported"); } @@ -316,7 +317,7 @@ public override int ReadByte() return retChar; } - #endregion Stream Overrides +#endregion Stream Overrides private void MakeMaps() { @@ -746,7 +747,7 @@ cache misses. private void SetupBlock() { - int[] cftab = new int[257]; + int[]? cftab = new int[257]; cftab[0] = 0; Array.Copy(unzftab, 0, cftab, 1, 256); diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs index f331ec657..1d1398b9d 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs @@ -1,6 +1,7 @@ using ICSharpCode.SharpZipLib.Checksum; using System; using System.IO; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.BZip2 { @@ -79,11 +80,11 @@ The current block size is 100000 * this number. private char[] selector = new char[BZip2Constants.MaximumSelectors]; private char[] selectorMtf = new char[BZip2Constants.MaximumSelectors]; - private byte[] block; - private int[] quadrant; - private int[] zptr; - private short[] szptr; - private int[] ftab; + private byte[] block = EmptyRefs.ByteArray; + private int[] quadrant = EmptyRefs.Int32Array; + private int[] zptr = EmptyRefs.Int32Array; + private short[] szptr = EmptyRefs.Int16Array; + private int[] ftab = EmptyRefs.Int32Array; private int nMTF; @@ -266,7 +267,7 @@ public override int ReadByte() /// The total number of bytes read. This might be less than the number of bytes /// requested if that number of bytes are not currently available, or zero /// if the end of the stream is reached. - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { throw new NotSupportedException("BZip2OutputStream Read not supported"); } @@ -710,14 +711,14 @@ private void SendMTFValues() remF -= aFreq; } - int[][] rfreq = new int[BZip2Constants.GroupCount][]; + int[][]? rfreq = new int[BZip2Constants.GroupCount][]; for (int i = 0; i < BZip2Constants.GroupCount; ++i) { rfreq[i] = new int[BZip2Constants.MaximumAlphaSize]; } - int[] fave = new int[BZip2Constants.GroupCount]; - short[] cost = new short[BZip2Constants.GroupCount]; + int[]? fave = new int[BZip2Constants.GroupCount]; + short[]? cost = new short[BZip2Constants.GroupCount]; /*--- Iterate up to N_ITERS times to improve the tables. ---*/ @@ -1691,7 +1692,7 @@ private void AllocateCompressStructures() zptr = new int[n]; ftab = new int[65537]; - if (block == null || quadrant == null || zptr == null || ftab == null) + if (block == EmptyRefs.ByteArray || quadrant == null || zptr == null || ftab == null) { // int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537; // compressOutOfMemory ( totalDraw, n ); diff --git a/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs b/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs new file mode 100644 index 000000000..4c183ff44 --- /dev/null +++ b/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ICSharpCode.SharpZipLib.Zip; + +namespace ICSharpCode.SharpZipLib.Core +{ + internal static class EmptyRefs + { +#if NET45 + public static byte[] ByteArray { get; } = new byte[0]; + public static int[] Int32Array { get; } = new int[0]; + public static short[] Int16Array {get; } = new short[0]; + public static ZipEntry[] ZipEntryArray { get; } = new ZipEntry[0]; +#else + public static byte[] ByteArray => Array.Empty(); + public static int[] Int32Array => Array.Empty(); + public static short[] Int16Array => Array.Empty(); + public static ZipEntry[] ZipEntryArray => Array.Empty(); +#endif + } +} diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs index eb14e2d49..18daa218c 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs @@ -23,7 +23,7 @@ public SharpZipBaseException() /// Initializes a new instance of the SharpZipBaseException class with a specified error message. /// /// A message describing the exception. - public SharpZipBaseException(string message) + public SharpZipBaseException(string? message) : base(message) { } @@ -34,7 +34,7 @@ public SharpZipBaseException(string message) /// /// A message describing the exception. /// The inner exception - public SharpZipBaseException(string message, Exception innerException) + public SharpZipBaseException(string? message, Exception? innerException) : base(message, innerException) { } @@ -50,7 +50,7 @@ public SharpZipBaseException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected SharpZipBaseException(SerializationInfo info, StreamingContext context) + protected SharpZipBaseException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs index 389b7d065..1c2eec699 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs @@ -21,7 +21,7 @@ public StreamDecodingException() : base(GenericMessage) { } /// Initializes a new instance of the StreamDecodingException class with a specified error message. /// /// A message describing the exception. - public StreamDecodingException(string message) : base(message) { } + public StreamDecodingException(string? message) : base(message) { } /// /// Initializes a new instance of the StreamDecodingException class with a specified @@ -29,7 +29,7 @@ public StreamDecodingException(string message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public StreamDecodingException(string message, Exception innerException) : base(message, innerException) { } + public StreamDecodingException(string? message, Exception? innerException) : base(message, innerException) { } /// /// Initializes a new instance of the StreamDecodingException class with serialized data. @@ -42,7 +42,7 @@ public StreamDecodingException(string message, Exception innerException) : base( /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected StreamDecodingException(SerializationInfo info, StreamingContext context) + protected StreamDecodingException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs index 5827e559d..2e8d2a252 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs @@ -20,7 +20,7 @@ public StreamUnsupportedException() : base(GenericMessage) { } /// Initializes a new instance of the StreamUnsupportedException class with a specified error message. /// /// A message describing the exception. - public StreamUnsupportedException(string message) : base(message) { } + public StreamUnsupportedException(string? message) : base(message) { } /// /// Initializes a new instance of the StreamUnsupportedException class with a specified @@ -28,7 +28,7 @@ public StreamUnsupportedException(string message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public StreamUnsupportedException(string message, Exception innerException) : base(message, innerException) { } + public StreamUnsupportedException(string? message, Exception? innerException) : base(message, innerException) { } /// /// Initializes a new instance of the StreamUnsupportedException class with serialized data. @@ -41,7 +41,7 @@ public StreamUnsupportedException(string message, Exception innerException) : ba /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected StreamUnsupportedException(SerializationInfo info, StreamingContext context) + protected StreamUnsupportedException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs index a35c49f03..a17d859fc 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs @@ -20,7 +20,7 @@ public UnexpectedEndOfStreamException() : base(GenericMessage) { } /// Initializes a new instance of the UnexpectedEndOfStreamException class with a specified error message. /// /// A message describing the exception. - public UnexpectedEndOfStreamException(string message) : base(message) { } + public UnexpectedEndOfStreamException(string? message) : base(message) { } /// /// Initializes a new instance of the UnexpectedEndOfStreamException class with a specified @@ -28,7 +28,7 @@ public UnexpectedEndOfStreamException(string message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public UnexpectedEndOfStreamException(string message, Exception innerException) : base(message, innerException) { } + public UnexpectedEndOfStreamException(string? message, Exception? innerException) : base(message, innerException) { } /// /// Initializes a new instance of the UnexpectedEndOfStreamException class with serialized data. @@ -41,7 +41,7 @@ public UnexpectedEndOfStreamException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected UnexpectedEndOfStreamException(SerializationInfo info, StreamingContext context) + protected UnexpectedEndOfStreamException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs index d41cf9882..f7a3c759e 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs @@ -13,7 +13,7 @@ public class ValueOutOfRangeException : StreamDecodingException /// Initializes a new instance of the ValueOutOfRangeException class naming the causing variable /// /// Name of the variable, use: nameof() - public ValueOutOfRangeException(string nameOfValue) + public ValueOutOfRangeException(string? nameOfValue) : base($"{nameOfValue} out of range") { } /// @@ -24,7 +24,7 @@ public ValueOutOfRangeException(string nameOfValue) /// The invalid value /// Expected maximum value /// Expected minimum value - public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, long minValue = 0) + public ValueOutOfRangeException(string? nameOfValue, long value, long maxValue, long minValue = 0) : this(nameOfValue, value.ToString(), maxValue.ToString(), minValue.ToString()) { } /// @@ -35,7 +35,7 @@ public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, l /// The invalid value /// Expected maximum value /// Expected minimum value - public ValueOutOfRangeException(string nameOfValue, string value, string maxValue, string minValue = "0") : + public ValueOutOfRangeException(string? nameOfValue, string? value, string? maxValue, string? minValue = "0") : base($"{nameOfValue} out of range: {value}, should be {minValue}..{maxValue}") { } @@ -43,7 +43,7 @@ private ValueOutOfRangeException() { } - private ValueOutOfRangeException(string message, Exception innerException) : base(message, innerException) + private ValueOutOfRangeException(string? message, Exception? innerException) : base(message, innerException) { } @@ -58,7 +58,7 @@ private ValueOutOfRangeException(string message, Exception innerException) : bas /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected ValueOutOfRangeException(SerializationInfo info, StreamingContext context) + protected ValueOutOfRangeException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs b/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs index 427e7d895..20f515684 100644 --- a/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs +++ b/src/ICSharpCode.SharpZipLib/Core/FileSystemScanner.cs @@ -2,136 +2,64 @@ namespace ICSharpCode.SharpZipLib.Core { - #region EventArgs - /// /// Event arguments for scanning. /// public class ScanEventArgs : EventArgs { - #region Constructors - /// /// Initialise a new instance of /// /// The file or directory name. - public ScanEventArgs(string name) + public ScanEventArgs(string? name) { - name_ = name; + Name = name; } - #endregion Constructors - /// /// The file or directory name for this event. /// - public string Name - { - get { return name_; } - } + public string? Name { get; } /// /// Get set a value indicating if scanning should continue or not. /// - public bool ContinueRunning - { - get { return continueRunning_; } - set { continueRunning_ = value; } - } - - #region Instance Fields - - private string name_; - private bool continueRunning_ = true; - - #endregion Instance Fields + public bool ContinueRunning { get; set; } = true; } /// /// Event arguments during processing of a single file or directory. /// - public class ProgressEventArgs : EventArgs + public class ProgressEventArgs : ScanEventArgs { - #region Constructors - /// /// Initialise a new instance of /// /// The file or directory name if known. /// The number of bytes processed so far /// The total number of bytes to process, 0 if not known - public ProgressEventArgs(string name, long processed, long target) - { - name_ = name; - processed_ = processed; - target_ = target; - } - - #endregion Constructors - - /// - /// The name for this event if known. - /// - public string Name - { - get { return name_; } - } - - /// - /// Get set a value indicating whether scanning should continue or not. - /// - public bool ContinueRunning + public ProgressEventArgs(string? name, long processed, long target): base(name) { - get { return continueRunning_; } - set { continueRunning_ = value; } + Processed = processed; + Target = target; } /// /// Get a percentage representing how much of the has been processed /// /// 0.0 to 100.0 percent; 0 if target is not known. - public float PercentComplete - { - get - { - float result; - if (target_ <= 0) - { - result = 0; - } - else - { - result = ((float)processed_ / (float)target_) * 100.0f; - } - return result; - } - } + public float PercentComplete => Target <= 0 ? 0 : ((float)Processed / Target) * 100.0f; /// /// The number of bytes processed so far /// - public long Processed - { - get { return processed_; } - } + public long Processed { get; } /// /// The number of bytes to process. /// - /// Target may be 0 or negative if the value isnt known. - public long Target - { - get { return target_; } - } - - #region Instance Fields - - private string name_; - private long processed_; - private long target_; - private bool continueRunning_ = true; - - #endregion Instance Fields + /// Target may be 0 or negative if the value isn't known. + public long Target { get; } } /// @@ -139,148 +67,87 @@ public long Target /// public class DirectoryEventArgs : ScanEventArgs { - #region Constructors - /// /// Initialize an instance of . /// /// The name for this directory. /// Flag value indicating if any matching files are contained in this directory. - public DirectoryEventArgs(string name, bool hasMatchingFiles) + public DirectoryEventArgs(string? name, bool hasMatchingFiles) : base(name) { - hasMatchingFiles_ = hasMatchingFiles; + HasMatchingFiles = hasMatchingFiles; } - #endregion Constructors - /// /// Get a value indicating if the directory contains any matching files or not. /// - public bool HasMatchingFiles - { - get { return hasMatchingFiles_; } - } - - private readonly - - #region Instance Fields - - bool hasMatchingFiles_; - - #endregion Instance Fields + public bool HasMatchingFiles { get; } } /// /// Arguments passed when scan failures are detected. /// - public class ScanFailureEventArgs : EventArgs + public class ScanFailureEventArgs : ScanEventArgs { - #region Constructors - - /// - /// Initialise a new instance of - /// - /// The name to apply. - /// The exception to use. - public ScanFailureEventArgs(string name, Exception e) - { - name_ = name; - exception_ = e; - continueRunning_ = true; - } - - #endregion Constructors - - /// - /// The applicable name. - /// - public string Name - { - get { return name_; } - } - - /// - /// The applicable exception. - /// - public Exception Exception + /// + public ScanFailureEventArgs(string? name, Exception? e): base(name) { - get { return exception_; } + Exception = e; } /// - /// Get / set a value indicating whether scanning should continue. + /// The exception that caused the failure. /// - public bool ContinueRunning - { - get { return continueRunning_; } - set { continueRunning_ = value; } - } - - #region Instance Fields - - private string name_; - private Exception exception_; - private bool continueRunning_; - - #endregion Instance Fields + public Exception? Exception { get; } } - #endregion EventArgs - - #region Delegates - /// /// Delegate invoked before starting to process a file. /// /// The source of the event /// The event arguments. - public delegate void ProcessFileHandler(object sender, ScanEventArgs e); + public delegate void ProcessFileHandler(object? sender, ScanEventArgs e); /// /// Delegate invoked during processing of a file or directory /// /// The source of the event /// The event arguments. - public delegate void ProgressHandler(object sender, ProgressEventArgs e); + public delegate void ProgressHandler(object? sender, ProgressEventArgs? e); /// /// Delegate invoked when a file has been completely processed. /// /// The source of the event /// The event arguments. - public delegate void CompletedFileHandler(object sender, ScanEventArgs e); + public delegate void CompletedFileHandler(object? sender, ScanEventArgs? e); /// /// Delegate invoked when a directory failure is detected. /// /// The source of the event /// The event arguments. - public delegate void DirectoryFailureHandler(object sender, ScanFailureEventArgs e); + public delegate void DirectoryFailureHandler(object? sender, ScanFailureEventArgs? e); /// /// Delegate invoked when a file failure is detected. /// /// The source of the event /// The event arguments. - public delegate void FileFailureHandler(object sender, ScanFailureEventArgs e); - - #endregion Delegates + public delegate void FileFailureHandler(object? sender, ScanFailureEventArgs? e); /// /// FileSystemScanner provides facilities scanning of files and directories. /// public class FileSystemScanner { - #region Constructors - /// /// Initialise a new instance of /// /// The file filter to apply when scanning. - public FileSystemScanner(string filter) + public FileSystemScanner(string? filter) { - fileFilter_ = new PathFilter(filter); + _fileFilter = new PathFilter(filter); } /// @@ -288,10 +155,10 @@ public FileSystemScanner(string filter) /// /// The file filter to apply. /// The directory filter to apply. - public FileSystemScanner(string fileFilter, string directoryFilter) + public FileSystemScanner(string? fileFilter, string? directoryFilter) { - fileFilter_ = new PathFilter(fileFilter); - directoryFilter_ = new PathFilter(directoryFilter); + _fileFilter = new PathFilter(fileFilter); + _directoryFilter = new PathFilter(directoryFilter); } /// @@ -300,7 +167,7 @@ public FileSystemScanner(string fileFilter, string directoryFilter) /// The file filter to apply. public FileSystemScanner(IScanFilter fileFilter) { - fileFilter_ = fileFilter; + _fileFilter = fileFilter; } /// @@ -308,59 +175,50 @@ public FileSystemScanner(IScanFilter fileFilter) /// /// The file filter to apply. /// The directory filter to apply. - public FileSystemScanner(IScanFilter fileFilter, IScanFilter directoryFilter) + public FileSystemScanner(IScanFilter fileFilter, IScanFilter? directoryFilter) { - fileFilter_ = fileFilter; - directoryFilter_ = directoryFilter; + _fileFilter = fileFilter; + _directoryFilter = directoryFilter; } - #endregion Constructors - - #region Delegates - /// /// Delegate to invoke when a directory is processed. /// - public event EventHandler ProcessDirectory; + public event EventHandler? ProcessDirectory; /// /// Delegate to invoke when a file is processed. /// - public ProcessFileHandler ProcessFile; + public ProcessFileHandler? ProcessFile; /// /// Delegate to invoke when processing for a file has finished. /// - public CompletedFileHandler CompletedFile; + public CompletedFileHandler? CompletedFile; /// /// Delegate to invoke when a directory failure is detected. /// - public DirectoryFailureHandler DirectoryFailure; + public DirectoryFailureHandler? DirectoryFailure; /// /// Delegate to invoke when a file failure is detected. /// - public FileFailureHandler FileFailure; - - #endregion Delegates + public FileFailureHandler? FileFailure; /// /// Raise the DirectoryFailure event. /// /// The directory name. /// The exception detected. - private bool OnDirectoryFailure(string directory, Exception e) + private bool OnDirectoryFailure(string? directory, Exception? e) { - DirectoryFailureHandler handler = DirectoryFailure; - bool result = (handler != null); - if (result) - { - var args = new ScanFailureEventArgs(directory, e); - handler(this, args); - alive_ = args.ContinueRunning; - } - return result; + if (DirectoryFailure is null) return false; + + var args = new ScanFailureEventArgs(directory, e); + DirectoryFailure(this, args); + _alive = args.ContinueRunning; + return true; } /// @@ -368,51 +226,40 @@ private bool OnDirectoryFailure(string directory, Exception e) /// /// The file name. /// The exception detected. - private bool OnFileFailure(string file, Exception e) + private bool OnFileFailure(string? file, Exception? e) { - FileFailureHandler handler = FileFailure; - - bool result = (handler != null); + if (FileFailure is null) return false; - if (result) - { - var args = new ScanFailureEventArgs(file, e); - FileFailure(this, args); - alive_ = args.ContinueRunning; - } - return result; + var args = new ScanFailureEventArgs(file, e); + FileFailure(this, args); + _alive = args.ContinueRunning; + return true; } /// /// Raise the ProcessFile event. /// /// The file name. - private void OnProcessFile(string file) + private void OnProcessFile(string? file) { - ProcessFileHandler handler = ProcessFile; - - if (handler != null) - { - var args = new ScanEventArgs(file); - handler(this, args); - alive_ = args.ContinueRunning; - } + if (ProcessFile is null) return; + + var args = new ScanEventArgs(file); + ProcessFile(this, args); + _alive = args.ContinueRunning; } /// /// Raise the complete file event /// /// The file name - private void OnCompleteFile(string file) + private void OnCompleteFile(string? file) { - CompletedFileHandler handler = CompletedFile; + if (CompletedFile is null) return; - if (handler != null) - { - var args = new ScanEventArgs(file); - handler(this, args); - alive_ = args.ContinueRunning; - } + var args = new ScanEventArgs(file); + CompletedFile(this, args); + _alive = args.ContinueRunning; } /// @@ -420,16 +267,13 @@ private void OnCompleteFile(string file) /// /// The directory name. /// Flag indicating if the directory has matching files. - private void OnProcessDirectory(string directory, bool hasMatchingFiles) + private void OnProcessDirectory(string? directory, bool hasMatchingFiles) { - EventHandler handler = ProcessDirectory; - - if (handler != null) - { - var args = new DirectoryEventArgs(directory, hasMatchingFiles); - handler(this, args); - alive_ = args.ContinueRunning; - } + if(ProcessDirectory is null) return; + + var args = new DirectoryEventArgs(directory, hasMatchingFiles); + ProcessDirectory(this, args); + _alive = args.ContinueRunning; } /// @@ -437,21 +281,21 @@ private void OnProcessDirectory(string directory, bool hasMatchingFiles) /// /// The base directory to scan. /// True to recurse subdirectories, false to scan a single directory. - public void Scan(string directory, bool recurse) + public void Scan(string? directory, bool recurse) { - alive_ = true; + _alive = true; ScanDir(directory, recurse); } - private void ScanDir(string directory, bool recurse) + private void ScanDir(string? directory, bool recurse) { try { - string[] names = System.IO.Directory.GetFiles(directory); - bool hasMatch = false; - for (int fileIndex = 0; fileIndex < names.Length; ++fileIndex) + string?[] names = System.IO.Directory.GetFiles(directory); + var hasMatch = false; + for (var fileIndex = 0; fileIndex < names.Length; ++fileIndex) { - if (!fileFilter_.IsMatch(names[fileIndex])) + if (!_fileFilter.IsMatch(names[fileIndex])) { names[fileIndex] = null; } @@ -463,19 +307,18 @@ private void ScanDir(string directory, bool recurse) OnProcessDirectory(directory, hasMatch); - if (alive_ && hasMatch) + if (_alive && hasMatch) { - foreach (string fileName in names) + foreach (var fileName in names) { try { - if (fileName != null) + if (fileName == null) continue; + + OnProcessFile(fileName); + if (!_alive) { - OnProcessFile(fileName); - if (!alive_) - { - break; - } + break; } } catch (Exception e) @@ -496,17 +339,17 @@ private void ScanDir(string directory, bool recurse) } } - if (alive_ && recurse) + if (_alive && recurse) { try { - string[] names = System.IO.Directory.GetDirectories(directory); - foreach (string fulldir in names) + var names = System.IO.Directory.GetDirectories(directory); + foreach (var fulldir in names) { - if ((directoryFilter_ == null) || (directoryFilter_.IsMatch(fulldir))) + if ((_directoryFilter == null) || (_directoryFilter.IsMatch(fulldir))) { ScanDir(fulldir, true); - if (!alive_) + if (!_alive) { break; } @@ -523,23 +366,19 @@ private void ScanDir(string directory, bool recurse) } } - #region Instance Fields - /// /// The file filter currently in use. /// - private IScanFilter fileFilter_; + private readonly IScanFilter _fileFilter; /// /// The directory filter currently in use. /// - private IScanFilter directoryFilter_; + private readonly IScanFilter? _directoryFilter; /// /// Flag indicating if scanning should continue running. /// - private bool alive_; - - #endregion Instance Fields + private bool _alive; } } diff --git a/src/ICSharpCode.SharpZipLib/Core/INameTransform.cs b/src/ICSharpCode.SharpZipLib/Core/INameTransform.cs index 492e2a9e6..c9d633528 100644 --- a/src/ICSharpCode.SharpZipLib/Core/INameTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Core/INameTransform.cs @@ -10,13 +10,13 @@ public interface INameTransform /// /// The name to transform. /// The transformed file name. - string TransformFile(string name); + string TransformFile(string? name); /// /// Given a directory name determine the transformed value. /// /// The name to transform. /// The transformed directory name - string TransformDirectory(string name); + string TransformDirectory(string? name); } } diff --git a/src/ICSharpCode.SharpZipLib/Core/IScanFilter.cs b/src/ICSharpCode.SharpZipLib/Core/IScanFilter.cs index ac07fd174..eb4c1b367 100644 --- a/src/ICSharpCode.SharpZipLib/Core/IScanFilter.cs +++ b/src/ICSharpCode.SharpZipLib/Core/IScanFilter.cs @@ -10,6 +10,6 @@ public interface IScanFilter /// /// The name to test. /// Returns true if the name matches the filter, false if it does not match. - bool IsMatch(string name); + bool IsMatch(string? name); } } diff --git a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs index 6647631bd..0c353af86 100644 --- a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs @@ -20,7 +20,7 @@ public InvalidNameException() : base("An invalid name was specified") /// Initializes a new instance of the InvalidNameException class with a specified error message. /// /// A message describing the exception. - public InvalidNameException(string message) : base(message) + public InvalidNameException(string? message) : base(message) { } @@ -30,7 +30,7 @@ public InvalidNameException(string message) : base(message) /// /// A message describing the exception. /// The inner exception - public InvalidNameException(string message, Exception innerException) : base(message, innerException) + public InvalidNameException(string? message, Exception? innerException) : base(message, innerException) { } @@ -45,7 +45,7 @@ public InvalidNameException(string message, Exception innerException) : base(mes /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected InvalidNameException(SerializationInfo info, StreamingContext context) + protected InvalidNameException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs b/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs index 57751891c..e678e3f36 100644 --- a/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs +++ b/src/ICSharpCode.SharpZipLib/Core/NameFilter.cs @@ -27,7 +27,7 @@ public class NameFilter : IScanFilter /// Construct an instance based on the filter expression passed /// /// The filter expression. - public NameFilter(string filter) + public NameFilter(string? filter) { filter_ = filter; inclusions_ = new List(); @@ -42,7 +42,7 @@ public NameFilter(string filter) /// /// The expression to test. /// True if expression is a valid false otherwise. - public static bool IsValidExpression(string expression) + public static bool IsValidExpression(string? expression) { bool result = true; try @@ -61,7 +61,7 @@ public static bool IsValidExpression(string expression) /// /// The filter expression to test. /// True if the expression is valid, false otherwise. - public static bool IsValidFilterExpression(string toTest) + public static bool IsValidFilterExpression(string? toTest) { bool result = true; @@ -161,7 +161,7 @@ public static string[] SplitQuoted(string original) /// Convert this filter to its string equivalent. /// /// The string equivalent for this filter. - public override string ToString() + public override string? ToString() { return filter_; } @@ -171,7 +171,7 @@ public override string ToString() /// /// The value to test. /// True if the value is included, false otherwise. - public bool IsIncluded(string name) + public bool IsIncluded(string? name) { bool result = false; if (inclusions_.Count == 0) @@ -197,7 +197,7 @@ public bool IsIncluded(string name) /// /// The value to test. /// True if the value is excluded, false otherwise. - public bool IsExcluded(string name) + public bool IsExcluded(string? name) { bool result = false; foreach (Regex r in exclusions_) @@ -218,7 +218,7 @@ public bool IsExcluded(string name) /// /// The value to test. /// True if the value matches, false otherwise. - public bool IsMatch(string name) + public bool IsMatch(string? name) { return (IsIncluded(name) && !IsExcluded(name)); } @@ -275,7 +275,7 @@ private void Compile() #region Instance Fields - private string filter_; + private string? filter_; private List inclusions_; private List exclusions_; diff --git a/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs b/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs index e70109c2c..d23596355 100644 --- a/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs +++ b/src/ICSharpCode.SharpZipLib/Core/PathFilter.cs @@ -16,7 +16,7 @@ public class PathFilter : IScanFilter /// Initialise a new instance of . /// /// The filter expression to apply. - public PathFilter(string filter) + public PathFilter(string? filter) { nameFilter_ = new NameFilter(filter); } @@ -31,7 +31,7 @@ public PathFilter(string filter) /// The name to test. /// True if the name matches, false otherwise. /// is used to get the full path before matching. - public virtual bool IsMatch(string name) + public virtual bool IsMatch(string? name) { bool result = false; @@ -68,7 +68,7 @@ public class ExtendedPathFilter : PathFilter /// The filter to apply. /// The minimum file size to include. /// The maximum file size to include. - public ExtendedPathFilter(string filter, + public ExtendedPathFilter(string? filter, long minSize, long maxSize) : base(filter) { @@ -82,7 +82,7 @@ public ExtendedPathFilter(string filter, /// The filter to apply. /// The minimum to include. /// The maximum to include. - public ExtendedPathFilter(string filter, + public ExtendedPathFilter(string? filter, DateTime minDate, DateTime maxDate) : base(filter) { @@ -98,7 +98,7 @@ public ExtendedPathFilter(string filter, /// The maximum file size to include. /// The minimum to include. /// The maximum to include. - public ExtendedPathFilter(string filter, + public ExtendedPathFilter(string? filter, long minSize, long maxSize, DateTime minDate, DateTime maxDate) : base(filter) @@ -119,7 +119,7 @@ public ExtendedPathFilter(string filter, /// The filename to test. /// True if the filter matches, false otherwise. /// The doesnt exist - public override bool IsMatch(string name) + public override bool IsMatch(string? name) { bool result = base.IsMatch(name); @@ -247,7 +247,7 @@ public class NameAndSizeFilter : PathFilter /// The filter to apply. /// The minimum file size to include. /// The maximum file size to include. - public NameAndSizeFilter(string filter, long minSize, long maxSize) + public NameAndSizeFilter(string? filter, long minSize, long maxSize) : base(filter) { MinSize = minSize; @@ -259,7 +259,7 @@ public NameAndSizeFilter(string filter, long minSize, long maxSize) /// /// The filename to test. /// True if the filter matches, false otherwise. - public override bool IsMatch(string name) + public override bool IsMatch(string? name) { bool result = base.IsMatch(name); diff --git a/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs b/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs index 6d0d9b304..f70968bcc 100644 --- a/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs +++ b/src/ICSharpCode.SharpZipLib/Core/StreamUtils.cs @@ -170,7 +170,7 @@ static public void Copy(Stream source, Stream destination, byte[] buffer) /// The name to use with the event. /// This form is specialised for use within #Zip to support events during archive operations. static public void Copy(Stream source, Stream destination, - byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, object sender, string name) + byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, object? sender, string? name) { Copy(source, destination, buffer, progressHandler, updateInterval, sender, name, -1); } @@ -191,7 +191,7 @@ static public void Copy(Stream source, Stream destination, static public void Copy(Stream source, Stream destination, byte[] buffer, ProgressHandler progressHandler, TimeSpan updateInterval, - object sender, string name, long fixedTarget) + object? sender, string? name, long fixedTarget) { if (source == null) { diff --git a/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs b/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs index 7a8c55e6e..962d535be 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/PkzipClassic.cs @@ -73,7 +73,7 @@ internal class PkzipClassicCryptoBase /// protected byte TransformByte() { - uint temp = ((keys[2] & 0xFFFF) | 2); + var temp = (_keys[2] & 0xFFFF) | 2; return (byte)((temp * (temp ^ 1)) >> 8); } @@ -93,10 +93,9 @@ protected void SetKeys(byte[] keyData) throw new InvalidOperationException("Key length is not valid"); } - keys = new uint[3]; - keys[0] = (uint)((keyData[3] << 24) | (keyData[2] << 16) | (keyData[1] << 8) | keyData[0]); - keys[1] = (uint)((keyData[7] << 24) | (keyData[6] << 16) | (keyData[5] << 8) | keyData[4]); - keys[2] = (uint)((keyData[11] << 24) | (keyData[10] << 16) | (keyData[9] << 8) | keyData[8]); + _keys[0] = (uint)((keyData[ 3] << 24) | (keyData[ 2] << 16) | (keyData[1] << 8) | keyData[0]); + _keys[1] = (uint)((keyData[ 7] << 24) | (keyData[ 6] << 16) | (keyData[5] << 8) | keyData[4]); + _keys[2] = (uint)((keyData[11] << 24) | (keyData[10] << 16) | (keyData[9] << 8) | keyData[8]); } /// @@ -104,10 +103,9 @@ protected void SetKeys(byte[] keyData) /// protected void UpdateKeys(byte ch) { - keys[0] = Crc32.ComputeCrc32(keys[0], ch); - keys[1] = keys[1] + (byte)keys[0]; - keys[1] = keys[1] * 134775813 + 1; - keys[2] = Crc32.ComputeCrc32(keys[2], (byte)(keys[1] >> 24)); + _keys[0] = Crc32.ComputeCrc32(_keys[0], ch); + _keys[1] = (_keys[1] + (byte)_keys[0]) * 134775813 + 1; + _keys[2] = Crc32.ComputeCrc32(_keys[2], (byte)(_keys[1] >> 24)); } /// @@ -115,14 +113,14 @@ protected void UpdateKeys(byte ch) /// protected void Reset() { - keys[0] = 0; - keys[1] = 0; - keys[2] = 0; + _keys[0] = 0; + _keys[1] = 0; + _keys[2] = 0; } #region Instance Fields - private uint[] keys; + private readonly uint[] _keys = new uint[3]; #endregion Instance Fields } @@ -414,12 +412,12 @@ public override byte[] Key { get { - if (key_ == null) + if (_key == null) { GenerateKey(); } - return (byte[])key_.Clone(); + return (byte[])(_key?.Clone() ?? new byte[0]); } set @@ -431,10 +429,10 @@ public override byte[] Key if (value.Length != 12) { - throw new CryptographicException("Key size is illegal"); + throw new CryptographicException("Key size is invalid"); } - key_ = (byte[])value.Clone(); + _key = (byte[])value.Clone(); } } @@ -443,22 +441,22 @@ public override byte[] Key /// public override void GenerateKey() { - key_ = new byte[12]; + _key = new byte[12]; var rnd = new Random(); - rnd.NextBytes(key_); + rnd.NextBytes(_key); } /// /// Create an encryptor. /// /// The key to use for this encryptor. - /// Initialisation vector for the new encryptor. + /// Initialization vector for the new encryptor. /// Returns a new PkzipClassic encryptor public override ICryptoTransform CreateEncryptor( - byte[] rgbKey, - byte[] rgbIV) + byte[]? rgbKey, + byte[]? rgbIV) { - key_ = rgbKey; + _key = rgbKey; return new PkzipClassicEncryptCryptoTransform(Key); } @@ -466,19 +464,19 @@ public override ICryptoTransform CreateEncryptor( /// Create a decryptor. /// /// Keys to use for this new decryptor. - /// Initialisation vector for the new decryptor. + /// Initialization vector for the new decryptor. /// Returns a new decryptor. public override ICryptoTransform CreateDecryptor( - byte[] rgbKey, - byte[] rgbIV) + byte[]? rgbKey, + byte[]? rgbIV) { - key_ = rgbKey; + _key = rgbKey; return new PkzipClassicDecryptCryptoTransform(Key); } #region Instance Fields - private byte[] key_; + private byte[]? _key; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs index 4f649e8a9..031dfb74a 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESStream.cs @@ -25,7 +25,6 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m { _stream = stream; _transform = transform; - _slideBuffer = new byte[1024]; // mode: // CryptoStreamMode.Read means we read from "stream" and pass decrypted to our Read() method. @@ -47,12 +46,13 @@ public ZipAESStream(Stream stream, ZipAESTransform transform, CryptoStreamMode m private Stream _stream; private ZipAESTransform _transform; - private byte[] _slideBuffer; + private byte[] _slideBuffer = new byte[1024]; private int _slideBufStartPos; private int _slideBufFreePos; + private bool _complete = false; // Buffer block transforms to enable partial reads - private byte[] _transformBuffer = null;// new byte[CRYPTO_BLOCK_SIZE]; + private byte[]? _transformBuffer = null;// new byte[CRYPTO_BLOCK_SIZE]; private int _transformBufferFreePos; private int _transformBufferStartPos; @@ -84,7 +84,7 @@ public override int Read(byte[] buffer, int offset, int count) } // Read more data from the input, if available - if (_slideBuffer != null) + if (!_complete) nBytes += ReadAndTransform(buffer, offset, count); return nBytes; @@ -105,7 +105,7 @@ private int ReadAndTransform(byte[] buffer, int offset, int count) // Maintain a read-ahead equal to the length of (crypto block + Auth Code). // When that runs out we can detect these final sections. int lengthToRead = BLOCK_AND_AUTH - byteCount; - if (_slideBuffer.Length - _slideBufFreePos < lengthToRead) + if (_slideBuffer!.Length - _slideBufFreePos < lengthToRead) { // Shift the data to the beginning of the buffer int iTo = 0; @@ -138,19 +138,18 @@ private int ReadAndTransform(byte[] buffer, int offset, int count) } else if (byteCount < AUTH_CODE_LENGTH) throw new Exception("Internal error missed auth code"); // Coding bug - // Final block done. Check Auth code. + + // Final block done. Check Auth code. byte[] calcAuthCode = _transform.GetAuthCode(); for (int i = 0; i < AUTH_CODE_LENGTH; i++) { if (calcAuthCode[i] != _slideBuffer[_slideBufStartPos + i]) { - throw new Exception("AES Authentication Code does not match. This is a super-CRC check on the data in the file after compression and encryption. \r\n" - + "The file may be damaged."); + throw new Exception("AES Authentication Code does not match. This is a super-CRC check on the data in the file after compression and encryption. The file may be damaged."); } } - // don't need this any more, so use it as a 'complete' flag - _slideBuffer = null; + _complete = true; break; // Reached the auth code } @@ -159,7 +158,7 @@ private int ReadAndTransform(byte[] buffer, int offset, int count) } // read some buffered data - private int ReadBufferedData(byte[] buffer, int offset, int count) + private int ReadBufferedData(byte[]? buffer, int offset, int count) { int copyCount = Math.Min(count, _transformBufferFreePos - _transformBufferStartPos); @@ -176,10 +175,7 @@ private int TransformAndBufferBlock(byte[] buffer, int offset, int count, int bl // If it's smaller, do it into a temporary buffer and copy the requested part bool bufferRequired = (blockSize > count); - if (bufferRequired && _transformBuffer == null) - _transformBuffer = new byte[CRYPTO_BLOCK_SIZE]; - - var targetBuffer = bufferRequired ? _transformBuffer : buffer; + var targetBuffer = bufferRequired ? _transformBuffer ??= new byte[CRYPTO_BLOCK_SIZE] : buffer; var targetOffset = bufferRequired ? 0 : offset; // Transform the data @@ -211,7 +207,7 @@ private int TransformAndBufferBlock(byte[] buffer, int offset, int count, int bl /// An array of bytes. This method copies count bytes from buffer to the current stream. /// The byte offset in buffer at which to begin copying bytes to the current stream. /// The number of bytes to be written to the current stream. - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { // ZipAESStream is used for reading but not for writing. Writing uses the ZipAESTransform directly. throw new NotImplementedException(); diff --git a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs index 437e25c10..4b34a4096 100644 --- a/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Encryption/ZipAESTransform.cs @@ -13,7 +13,7 @@ class IncrementalHash : HMACSHA1 { bool _finalised; public IncrementalHash(byte[] key) : base(key) { } - public static IncrementalHash CreateHMAC(string n, byte[] key) => new IncrementalHash(key); + public static IncrementalHash CreateHMAC(string _, byte[] key) => new IncrementalHash(key); public void AppendData(byte[] buffer, int offset, int count) => TransformBlock(buffer, offset, count, buffer, offset); public byte[] GetHashAndReset() { @@ -29,7 +29,7 @@ public byte[] GetHashAndReset() static class HashAlgorithmName { - public static string SHA1 = null; + public static readonly string SHA1 = string.Empty; } #endif @@ -50,7 +50,7 @@ static class HashAlgorithmName private int _encrPos; private byte[] _pwdVerifier; private IncrementalHash _hmacsha1; - private byte[] _authCode = null; + private byte[]? _authCode = null; private bool _writeMode; @@ -63,7 +63,7 @@ static class HashAlgorithmName /// The encryption strength, in bytes eg 16 for 128 bits. /// True when creating a zip, false when reading. For the AuthCode. /// - public ZipAESTransform(string key, byte[] saltBytes, int blockSize, bool writeMode) + public ZipAESTransform(string? key, byte[] saltBytes, int blockSize, bool writeMode) { if (blockSize != 16 && blockSize != 32) // 24 valid for AES but not supported by Winzip throw new Exception("Invalid blocksize " + blockSize + ". Must be 16 or 32."); @@ -157,7 +157,7 @@ public byte[] GetAuthCode() /// /// Not implemented. /// - public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) + public byte[] TransformFinalBlock(byte[]? inputBuffer, int inputOffset, int inputCount) { if(inputCount > 0) { diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs index e7e4763da..50c26c1bc 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs @@ -18,7 +18,7 @@ public static class GZip /// The output stream to receive the decompressed data. /// Both streams are closed on completion if true. /// Input or output stream is null - public static void Decompress(Stream inStream, Stream outStream, bool isStreamOwner) + public static void Decompress(Stream? inStream, Stream? outStream, bool isStreamOwner) { if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); @@ -56,7 +56,7 @@ public static void Decompress(Stream inStream, Stream outStream, bool isStreamOw /// Input or output stream is null /// Buffer Size is smaller than 512 /// Compression level outside 0-9 - public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int bufferSize = 512, int level = 6) + public static void Compress(Stream? inStream, Stream? outStream, bool isStreamOwner, int bufferSize = 512, int level = 6) { if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs b/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs index a0ec6bb51..dbf1acb2a 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs @@ -20,7 +20,7 @@ public GZipException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public GZipException(string message) + public GZipException(string? message) : base(message) { } @@ -30,7 +30,7 @@ public GZipException(string message) /// /// A that describes the error. /// The that caused this exception. - public GZipException(string message, Exception innerException) + public GZipException(string? message, Exception? innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public GZipException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected GZipException(SerializationInfo info, StreamingContext context) + protected GZipException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs b/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs index a924a7ffc..7f4a62ddd 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GzipInputStream.cs @@ -40,7 +40,7 @@ public class GZipInputStream : InflaterInputStream /// /// CRC-32 value for uncompressed data /// - protected Crc32 crc; + protected Crc32 crc = new Crc32(); /// /// Flag to indicate if we've read the GZIP header yet for the current member (block of compressed data). @@ -156,7 +156,7 @@ public override int Read(byte[] buffer, int offset, int count) private bool ReadHeader() { // Initialize CRC for this block - crc = new Crc32(); + crc.Reset(); // Make sure there is data in file. We can't rely on ReadLeByte() to fill the buffer, as this could be EOF, // which is fine, but ReadLeByte() throws an exception if it doesn't find data, so we do this part ourselves. diff --git a/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs b/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs index 1d5c44c3c..c5b0d4fcb 100644 --- a/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs +++ b/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs @@ -20,7 +20,7 @@ public LzwException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public LzwException(string message) + public LzwException(string? message) : base(message) { } @@ -30,7 +30,7 @@ public LzwException(string message) /// /// A that describes the error. /// The that caused this exception. - public LzwException(string message, Exception innerException) + public LzwException(string? message, Exception? innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public LzwException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected LzwException(SerializationInfo info, StreamingContext context) + protected LzwException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs b/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs index 1045ef778..90acc8029 100644 --- a/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Lzw/LzwInputStream.cs @@ -99,9 +99,9 @@ public override int Read(byte[] buffer, int offset, int count) /* Using local copies of various variables speeds things up by as * much as 30% in Java! Performance not tested in C#. */ - int[] lTabPrefix = tabPrefix; - byte[] lTabSuffix = tabSuffix; - byte[] lStack = stack; + int[] lTabPrefix = tabPrefix!; + byte[] lTabSuffix = tabSuffix!; + byte[] lStack = stack!; int lNBits = nBits; int lMaxCode = maxCode; int lMaxMaxCode = maxMaxCode; @@ -489,7 +489,7 @@ public override void SetLength(long value) /// The offset of the first byte to write. /// The number of bytes to write. /// Any access - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { throw new NotSupportedException("InflaterInputStream Write not supported"); } @@ -540,10 +540,10 @@ protected override void Dispose(bool disposing) private const int TBL_FIRST = TBL_CLEAR + 1; - private int[] tabPrefix; - private byte[] tabSuffix; + private int[]? tabPrefix; + private byte[]? tabSuffix; private readonly int[] zeros = new int[256]; - private byte[] stack; + private byte[]? stack; // various state private bool blockMode; diff --git a/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs b/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs index 9f385e425..959b585ff 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs @@ -21,7 +21,7 @@ public InvalidHeaderException() /// Initialises a new instance of the InvalidHeaderException class with a specified message. /// /// Message describing the exception cause. - public InvalidHeaderException(string message) + public InvalidHeaderException(string? message) : base(message) { } @@ -31,7 +31,7 @@ public InvalidHeaderException(string message) /// /// Message describing the problem. /// The exception that is the cause of the current exception. - public InvalidHeaderException(string message, Exception exception) + public InvalidHeaderException(string? message, Exception? exception) : base(message, exception) { } @@ -47,7 +47,7 @@ public InvalidHeaderException(string message, Exception exception) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected InvalidHeaderException(SerializationInfo info, StreamingContext context) + protected InvalidHeaderException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs index 562480a3c..85856134a 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs @@ -7,7 +7,7 @@ namespace ICSharpCode.SharpZipLib.Tar /// /// Used to advise clients of 'events' while processing archives /// - public delegate void ProgressMessageHandler(TarArchive archive, TarEntry entry, string message); + public delegate void ProgressMessageHandler(TarArchive? archive, TarEntry? entry, string? message); /// /// The TarArchive class implements the concept of a @@ -35,16 +35,16 @@ public class TarArchive : IDisposable /// /// Client hook allowing detailed information to be reported during processing /// - public event ProgressMessageHandler ProgressMessageEvent; + public event ProgressMessageHandler? ProgressMessageEvent; /// /// Raises the ProgressMessage event /// /// The TarEntry for this event /// message for this event. Null is no message - protected virtual void OnProgressMessageEvent(TarEntry entry, string message) + protected virtual void OnProgressMessageEvent(TarEntry? entry, string? message) { - ProgressMessageHandler handler = ProgressMessageEvent; + ProgressMessageHandler? handler = ProgressMessageEvent; if (handler != null) { handler(this, entry, message); @@ -53,25 +53,13 @@ protected virtual void OnProgressMessageEvent(TarEntry entry, string message) #region Constructors - /// - /// Constructor for a default . - /// - protected TarArchive() - { - } - /// /// Initialise a TarArchive for input. /// /// The to use for input. protected TarArchive(TarInputStream stream) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - tarIn = stream; + tarIn = stream ?? throw new ArgumentNullException(nameof(stream)); } /// @@ -80,12 +68,7 @@ protected TarArchive(TarInputStream stream) /// The to use for output. protected TarArchive(TarOutputStream stream) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } - - tarOut = stream; + tarOut = stream ?? throw new ArgumentNullException(nameof(stream)); } #endregion Constructors @@ -115,7 +98,7 @@ public static TarArchive CreateInputTarArchive(Stream inputStream) /// The stream to retrieve archive data from. /// The used for the Name fields, or null for ASCII only /// Returns a new suitable for reading from. - public static TarArchive CreateInputTarArchive(Stream inputStream, Encoding nameEncoding) + public static TarArchive CreateInputTarArchive(Stream inputStream, Encoding? nameEncoding) { if (inputStream == null) { @@ -155,7 +138,7 @@ public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFact /// The blocking factor to apply /// The used for the Name fields, or null for ASCII only /// Returns a suitable for reading. - public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFactor, Encoding nameEncoding) + public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFactor, Encoding? nameEncoding) { if (inputStream == null) { @@ -175,7 +158,7 @@ public static TarArchive CreateInputTarArchive(Stream inputStream, int blockFact /// The to write to /// The used for the Name fields, or null for ASCII only /// Returns a suitable for writing. - public static TarArchive CreateOutputTarArchive(Stream outputStream, Encoding nameEncoding) + public static TarArchive CreateOutputTarArchive(Stream outputStream, Encoding? nameEncoding) { if (outputStream == null) { @@ -222,7 +205,7 @@ public static TarArchive CreateOutputTarArchive(Stream outputStream, int blockFa /// The blocking factor to use for buffering. /// The used for the Name fields, or null for ASCII only /// Returns a suitable for writing. - public static TarArchive CreateOutputTarArchive(Stream outputStream, int blockFactor, Encoding nameEncoding) + public static TarArchive CreateOutputTarArchive(Stream outputStream, int blockFactor, Encoding? nameEncoding) { if (outputStream == null) { @@ -309,7 +292,7 @@ public void SetAsciiTranslation(bool translateAsciiFiles) /// PathPrefix is added to entry names as they are written if the value is not null. /// A slash character is appended after PathPrefix /// - public string PathPrefix + public string? PathPrefix { get { @@ -336,7 +319,7 @@ public string PathPrefix /// RootPath is removed from entry names if it is found at the /// beginning of the name. /// - public string RootPath + public string? RootPath { get { @@ -355,7 +338,7 @@ public string RootPath throw new ObjectDisposedException("TarArchive"); } // Convert to forward slashes for matching. Trim trailing / for correct final path - rootPath = value.Replace('\\', '/').TrimEnd('/'); + rootPath = value?.Replace('\\', '/')?.TrimEnd('/') ?? string.Empty; } } @@ -449,7 +432,7 @@ public int UserId /// /// The current user name. /// - public string UserName + public string? UserName { get { @@ -491,7 +474,7 @@ public int GroupId /// /// The current group name. /// - public string GroupName + public string? GroupName { get { @@ -543,11 +526,11 @@ public bool IsStreamOwner { set { - if (tarIn != null) + if (tarIn is {}) { tarIn.IsStreamOwner = value; } - else + else if(tarOut is {}) { tarOut.IsStreamOwner = value; } @@ -576,14 +559,8 @@ public void ListContents() throw new ObjectDisposedException("TarArchive"); } - while (true) + while (tarIn?.GetNextEntry() is { } entry) { - TarEntry entry = tarIn.GetNextEntry(); - - if (entry == null) - { - break; - } OnProgressMessageEvent(entry, null); } } @@ -594,22 +571,15 @@ public void ListContents() /// /// The destination directory into which to extract. /// - public void ExtractContents(string destinationDirectory) + public void ExtractContents(string? destinationDirectory) { if (isDisposed) { throw new ObjectDisposedException("TarArchive"); } - while (true) + while (tarIn?.GetNextEntry() is { } entry) { - TarEntry entry = tarIn.GetNextEntry(); - - if (entry == null) - { - break; - } - if (entry.TarHeader.TypeFlag == TarHeader.LF_LINK || entry.TarHeader.TypeFlag == TarHeader.LF_SYMLINK) continue; @@ -627,7 +597,7 @@ public void ExtractContents(string destinationDirectory) /// /// The TarEntry returned by tarIn.GetNextEntry(). /// - private void ExtractEntry(string destDir, TarEntry entry) + private void ExtractEntry(string? destDir, TarEntry entry) { OnProgressMessageEvent(entry, null); @@ -669,28 +639,29 @@ private void ExtractEntry(string destDir, TarEntry entry) } } - if (process) + if (!process) return; + + using (var outputStream = File.Create(destFile)) { - using (var outputStream = File.Create(destFile)) + if (this.asciiTranslate) { - if (this.asciiTranslate) - { - // May need to translate the file. - ExtractAndTranslateEntry(destFile, outputStream); - } - else - { - // If translation is disabled, just copy the entry across directly. - tarIn.CopyEntryContents(outputStream); - } + // May need to translate the file. + ExtractAndTranslateEntry(destFile, outputStream); + } + else + { + // If translation is disabled, just copy the entry across directly. + tarIn?.CopyEntryContents(outputStream); } } } } // Extract a TAR entry, and perform an ASCII translation if required. - private void ExtractAndTranslateEntry(string destFile, Stream outputStream) + private void ExtractAndTranslateEntry(string? destFile, Stream outputStream) { + if(tarIn is null) throw new InvalidOperationException("Input TAR stream is null"); + bool asciiTrans = !IsBinary(destFile); if (asciiTrans) @@ -785,11 +756,13 @@ public void WriteEntry(TarEntry sourceEntry, bool recurse) /// private void WriteEntryCore(TarEntry sourceEntry, bool recurse) { - string tempFileName = null; - string entryFilename = sourceEntry.File; + string? tempFileName = null; + string? entryFilename = sourceEntry.File; var entry = (TarEntry)sourceEntry.Clone(); + if(tarOut is null) throw new InvalidOperationException("Output TAR stream is null"); + if (applyUserInfoOverrides) { entry.GroupId = groupId; @@ -831,13 +804,13 @@ private void WriteEntryCore(TarEntry sourceEntry, bool recurse) } } - string newName = null; + string? newName = null; - if (!String.IsNullOrEmpty(rootPath)) + if (!string.IsNullOrEmpty(rootPath)) { if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase)) { - newName = entry.Name.Substring(rootPath.Length + 1); + newName = entry.Name.Substring(rootPath!.Length + 1); } } @@ -943,7 +916,7 @@ public virtual void Close() Dispose(false); } - private static void EnsureDirectoryExists(string directoryName) + private static void EnsureDirectoryExists(string? directoryName) { if (!Directory.Exists(directoryName)) { @@ -962,7 +935,7 @@ private static void EnsureDirectoryExists(string directoryName) // It no longer reads entire files into memory but is still a weak test! // This assumes that byte values 0-7, 14-31 or 255 are binary // and that all non text files contain one of these values - private static bool IsBinary(string filename) + private static bool IsBinary(string? filename) { using (FileStream fs = File.OpenRead(filename)) { @@ -993,13 +966,13 @@ private static bool IsBinary(string filename) private int groupId; private string groupName = string.Empty; - private string rootPath; - private string pathPrefix; + private string? rootPath; + private string? pathPrefix; private bool applyUserInfoOverrides; - private TarInputStream tarIn; - private TarOutputStream tarOut; + private TarInputStream? tarIn; + private TarOutputStream? tarOut; private bool isDisposed; #endregion Instance Fields diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs b/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs index 744c13189..7ce22652f 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs @@ -584,10 +584,10 @@ public void Close() #region Instance Fields - private Stream inputStream; - private Stream outputStream; + private Stream? inputStream; + private Stream? outputStream; - private byte[] recordBuffer; + private byte[]? recordBuffer; private int currentBlockIndex; private int currentRecordIndex; diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs index 64a1e5e18..a3ff34c16 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs @@ -65,7 +65,7 @@ public TarEntry(byte[] headerBuffer) : this(headerBuffer, null) /// /// The used for the Name fields, or null for ASCII only /// - public TarEntry(byte[] headerBuffer, Encoding nameEncoding) + public TarEntry(byte[] headerBuffer, Encoding? nameEncoding) { header = new TarHeader(); header.ParseBuffer(headerBuffer, nameEncoding); @@ -138,7 +138,7 @@ public static TarEntry CreateEntryFromFile(string fileName) /// /// True if the entries are equal; false if not. /// - public override bool Equals(object obj) + public override bool Equals(object? obj) { var localEntry = obj as TarEntry; @@ -185,27 +185,15 @@ public bool IsDescendent(TarEntry toTest) /// /// This entry's TarHeader. /// - public TarHeader TarHeader - { - get - { - return header; - } - } + public TarHeader TarHeader => header; /// /// Get/Set this entry's name. /// public string Name { - get - { - return header.Name; - } - set - { - header.Name = value; - } + get => header.Name; + set => header.Name = value; } /// @@ -213,14 +201,8 @@ public string Name /// public int UserId { - get - { - return header.UserId; - } - set - { - header.UserId = value; - } + get => header.UserId; + set => header.UserId = value; } /// @@ -228,14 +210,8 @@ public int UserId /// public int GroupId { - get - { - return header.GroupId; - } - set - { - header.GroupId = value; - } + get => header.GroupId; + set => header.GroupId = value; } /// @@ -243,14 +219,8 @@ public int GroupId /// public string UserName { - get - { - return header.UserName; - } - set - { - header.UserName = value; - } + get => header.UserName; + set => header.UserName = value; } /// @@ -258,14 +228,8 @@ public string UserName /// public string GroupName { - get - { - return header.GroupName; - } - set - { - header.GroupName = value; - } + get => header.GroupName; + set => header.GroupName = value; } /// @@ -303,14 +267,8 @@ public void SetNames(string userName, string groupName) /// public DateTime ModTime { - get - { - return header.ModTime; - } - set - { - header.ModTime = value; - } + get => header.ModTime; + set => header.ModTime = value; } /// @@ -319,27 +277,15 @@ public DateTime ModTime /// /// This entry's file. /// - public string File - { - get - { - return file; - } - } + public string? File => file; /// /// Get/set this entry's recorded file size. /// public long Size { - get - { - return header.Size; - } - set - { - header.Size = value; - } + get => header.Size; + set => header.Size = value; } /// @@ -500,7 +446,7 @@ public void WriteEntryHeader(byte[] outBuffer) /// /// The used for the Name fields, or null for ASCII only /// - public void WriteEntryHeader(byte[] outBuffer, Encoding nameEncoding) + public void WriteEntryHeader(byte[] outBuffer, Encoding? nameEncoding) { header.WriteHeader(outBuffer, nameEncoding); } @@ -534,7 +480,7 @@ static public void AdjustEntryName(byte[] buffer, string newName) /// /// The used for the Name fields, or null for ASCII only /// - static public void AdjustEntryName(byte[] buffer, string newName, Encoding nameEncoding) + static public void AdjustEntryName(byte[] buffer, string newName, Encoding? nameEncoding) { TarHeader.GetNameBytes(newName, buffer, 0, TarHeader.NAMELEN, nameEncoding); } @@ -585,7 +531,7 @@ static public void NameTarHeader(TarHeader header, string name) /// /// The name of the file this entry represents or null if the entry is not based on a file. /// - private string file; + private string? file; /// /// The entry's header information. diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs index 9d448ca7d..0de1133a3 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs @@ -20,7 +20,7 @@ public TarException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public TarException(string message) + public TarException(string? message) : base(message) { } @@ -30,7 +30,7 @@ public TarException(string message) /// /// A that describes the error. /// The that caused this exception. - public TarException(string message, Exception innerException) + public TarException(string? message, Exception? innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public TarException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected TarException(SerializationInfo info, StreamingContext context) + protected TarException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs b/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs index d1d438ad0..fe63eb370 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarExtendedHeaderReader.cs @@ -8,25 +8,23 @@ namespace ICSharpCode.SharpZipLib.Tar /// public class TarExtendedHeaderReader { - private const byte LENGTH = 0; - private const byte KEY = 1; - private const byte VALUE = 2; - private const byte END = 3; + private const byte Length = 0; + private const byte Key = 1; + private const byte Value = 2; + private const byte End = 3; - private readonly Dictionary headers = new Dictionary(); + private string[] _headerParts = new string[3]; - private string[] headerParts = new string[3]; + private int _bbIndex; + private byte[] _byteBuffer = new byte[4]; + private char[] _charBuffer = new char[4]; - private int bbIndex; - private byte[] byteBuffer; - private char[] charBuffer; + private readonly StringBuilder _sb = new StringBuilder(); + private readonly Decoder _decoder = Encoding.UTF8.GetDecoder(); - private readonly StringBuilder sb = new StringBuilder(); - private readonly Decoder decoder = Encoding.UTF8.GetDecoder(); + private int _state = Length; - private int state = LENGTH; - - private static readonly byte[] StateNext = new[] { (byte)' ', (byte)'=', (byte)'\n' }; + private static readonly byte[] StateNext = { (byte)' ', (byte)'=', (byte)'\n' }; /// /// Creates a new . @@ -47,23 +45,23 @@ public void Read(byte[] buffer, int length) { byte next = buffer[i]; - if (next == StateNext[state]) + if (next == StateNext[_state]) { Flush(); - headerParts[state] = sb.ToString(); - sb.Clear(); + _headerParts[_state] = _sb.ToString(); + _sb.Clear(); - if (++state == END) + if (++_state == End) { - headers.Add(headerParts[KEY], headerParts[VALUE]); - headerParts = new string[3]; - state = LENGTH; + Headers.Add(_headerParts[Key], _headerParts[Value]); + _headerParts = new string[3]; + _state = Length; } } else { - byteBuffer[bbIndex++] = next; - if (bbIndex == 4) + _byteBuffer[_bbIndex++] = next; + if (_bbIndex == 4) Flush(); } } @@ -71,29 +69,22 @@ public void Read(byte[] buffer, int length) private void Flush() { - decoder.Convert(byteBuffer, 0, bbIndex, charBuffer, 0, 4, false, out int bytesUsed, out int charsUsed, out bool completed); + _decoder.Convert(_byteBuffer, 0, _bbIndex, _charBuffer, 0, 4, false, out _, out var charsUsed, out _); - sb.Append(charBuffer, 0, charsUsed); + _sb.Append(_charBuffer, 0, charsUsed); ResetBuffers(); } private void ResetBuffers() { - charBuffer = new char[4]; - byteBuffer = new byte[4]; - bbIndex = 0; + _charBuffer = new char[4]; + _byteBuffer = new byte[4]; + _bbIndex = 0; } /// /// Returns the parsed headers as key-value strings /// - public Dictionary Headers - { - get - { - // TODO: Check for invalid state? -NM 2018-07-01 - return headers; - } - } + public Dictionary Headers { get; } = new Dictionary(); } } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs b/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs index 3bd1bdffe..34339481e 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarHeader.cs @@ -247,16 +247,12 @@ public class TarHeader /// public TarHeader() { - Magic = TMAGIC; Version = " "; - Name = ""; - LinkName = ""; - UserId = defaultUserId; GroupId = defaultGroupId; - UserName = defaultUser; - GroupName = defaultGroupName; + userName = defaultUser; + groupName = defaultGroupName; Size = 0; } @@ -270,15 +266,8 @@ public TarHeader() /// Thrown when attempting to set the property to null. public string Name { - get { return name; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - name = value; - } + get => name; + set => name = value ?? throw new ArgumentNullException(nameof(value)); } /// @@ -286,19 +275,12 @@ public string Name /// /// The entry's name. [Obsolete("Use the Name property instead", true)] - public string GetName() - { - return name; - } + public string GetName() => name; /// /// Get/set the entry's Unix style permission mode. /// - public int Mode - { - get { return mode; } - set { mode = value; } - } + public int Mode { get; set; } /// /// The entry's user id. @@ -307,11 +289,7 @@ public int Mode /// This is only directly relevant to unix systems. /// The default is zero. /// - public int UserId - { - get { return userId; } - set { userId = value; } - } + public int UserId { get; set; } /// /// Get/set the entry's group id. @@ -320,11 +298,7 @@ public int UserId /// This is only directly relevant to linux/unix systems. /// The default value is zero. /// - public int GroupId - { - get { return groupId; } - set { groupId = value; } - } + public int GroupId { get; set; } /// /// Get/set the entry's size. @@ -332,15 +306,8 @@ public int GroupId /// Thrown when setting the size to less than zero. public long Size { - get { return size; } - set - { - if (value < 0) - { - throw new ArgumentOutOfRangeException(nameof(value), "Cannot be less than zero"); - } - size = value; - } + get => size; + set => size = value < 0 ? throw new ArgumentOutOfRangeException(nameof(value), "Cannot be less than zero") : value; } /// @@ -352,41 +319,26 @@ public long Size /// Thrown when setting the date time to less than 1/1/1970. public DateTime ModTime { - get { return modTime; } - set - { - if (value < dateTime1970) - { - throw new ArgumentOutOfRangeException(nameof(value), "ModTime cannot be before Jan 1st 1970"); - } - modTime = new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second); - } + get => modTime; + set => modTime = value < dateTime1970 + ? throw new ArgumentOutOfRangeException(nameof(value), "ModTime cannot be before Jan 1st 1970") + : new DateTime(value.Year, value.Month, value.Day, value.Hour, value.Minute, value.Second); } /// /// Get the entry's checksum. This is only valid/updated after writing or reading an entry. /// - public int Checksum - { - get { return checksum; } - } + public int Checksum { get; private set; } /// /// Get value of true if the header checksum is valid, false otherwise. /// - public bool IsChecksumValid - { - get { return isChecksumValid; } - } + public bool IsChecksumValid { get; private set; } /// /// Get/set the entry's type flag. /// - public byte TypeFlag - { - get { return typeFlag; } - set { typeFlag = value; } - } + public byte TypeFlag { get; set; } /// /// The entry's link name. @@ -394,15 +346,8 @@ public byte TypeFlag /// Thrown when attempting to set LinkName to null. public string LinkName { - get { return linkName; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - linkName = value; - } + get => linkName; + set => linkName = value ?? throw new ArgumentNullException(nameof(value)); } /// @@ -411,15 +356,8 @@ public string LinkName /// Thrown when attempting to set Magic to null. public string Magic { - get { return magic; } - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - magic = value; - } + get => magic; + set => magic = value ?? throw new ArgumentNullException(nameof(value)); } /// @@ -428,19 +366,8 @@ public string Magic /// Thrown when attempting to set Version to null. public string Version { - get - { - return version; - } - - set - { - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - version = value; - } + get => version; + set => version = value ?? throw new ArgumentNullException(nameof(value)); } /// @@ -448,23 +375,8 @@ public string Version /// public string UserName { - get { return userName; } - set - { - if (value != null) - { - userName = value.Substring(0, Math.Min(UNAMELEN, value.Length)); - } - else - { - string currentUser = "user"; - if (currentUser.Length > UNAMELEN) - { - currentUser = currentUser.Substring(0, UNAMELEN); - } - userName = currentUser; - } - } + get => userName; + set => userName = value?.Substring(0, Math.Min(UNAMELEN, value.Length)) ?? "user"; } /// @@ -475,37 +387,19 @@ public string UserName /// public string GroupName { - get { return groupName; } - set - { - if (value == null) - { - groupName = "None"; - } - else - { - groupName = value; - } - } + get => groupName; + set => groupName = value ?? "None"; } /// /// Get/set the entry's major device number. /// - public int DevMajor - { - get { return devMajor; } - set { devMajor = value; } - } + public int DevMajor { get; set; } /// /// Get/set the entry's minor device number. /// - public int DevMinor - { - get { return devMinor; } - set { devMinor = value; } - } + public int DevMinor { get; set; } #endregion Properties @@ -531,7 +425,7 @@ public object Clone() /// /// The used for the Name field, or null for ASCII only /// - public void ParseBuffer(byte[] header, Encoding nameEncoding) + public void ParseBuffer(byte[] header, Encoding? nameEncoding) { if (header == null) { @@ -543,7 +437,7 @@ public void ParseBuffer(byte[] header, Encoding nameEncoding) name = ParseName(header, offset, NAMELEN, nameEncoding).ToString(); offset += NAMELEN; - mode = (int)ParseOctal(header, offset, MODELEN); + Mode = (int)ParseOctal(header, offset, MODELEN); offset += MODELEN; UserId = (int)ParseOctal(header, offset, UIDLEN); @@ -558,7 +452,7 @@ public void ParseBuffer(byte[] header, Encoding nameEncoding) ModTime = GetDateTimeFromCTime(ParseOctal(header, offset, MODTIMELEN)); offset += MODTIMELEN; - checksum = (int)ParseOctal(header, offset, CHKSUMLEN); + Checksum = (int)ParseOctal(header, offset, CHKSUMLEN); offset += CHKSUMLEN; TypeFlag = header[offset++]; @@ -590,7 +484,7 @@ public void ParseBuffer(byte[] header, Encoding nameEncoding) if (!string.IsNullOrEmpty(prefix)) Name = prefix + '/' + Name; } - isChecksumValid = Checksum == TarHeader.MakeCheckSum(header); + IsChecksumValid = Checksum == TarHeader.MakeCheckSum(header); } /// @@ -620,7 +514,7 @@ public void WriteHeader(byte[] outBuffer) /// /// output buffer for header information /// The used for the Name field, or null for ASCII only - public void WriteHeader(byte[] outBuffer, Encoding nameEncoding) + public void WriteHeader(byte[] outBuffer, Encoding? nameEncoding) { if (outBuffer == null) { @@ -630,7 +524,7 @@ public void WriteHeader(byte[] outBuffer, Encoding nameEncoding) int offset = 0; offset = GetNameBytes(Name, outBuffer, offset, NAMELEN, nameEncoding); - offset = GetOctalBytes(mode, outBuffer, offset, MODELEN); + offset = GetOctalBytes(Mode, outBuffer, offset, MODELEN); offset = GetOctalBytes(UserId, outBuffer, offset, UIDLEN); offset = GetOctalBytes(GroupId, outBuffer, offset, GIDLEN); @@ -662,10 +556,10 @@ public void WriteHeader(byte[] outBuffer, Encoding nameEncoding) outBuffer[offset++] = 0; } - checksum = ComputeCheckSum(outBuffer); + Checksum = ComputeCheckSum(outBuffer); - GetCheckSumOctalBytes(checksum, outBuffer, csOffset, CHKSUMLEN); - isChecksumValid = true; + GetCheckSumOctalBytes(Checksum, outBuffer, csOffset, CHKSUMLEN); + IsChecksumValid = true; } /// @@ -682,7 +576,7 @@ public override int GetHashCode() /// /// The object to compare with. /// true if the objects are equal, false otherwise. - public override bool Equals(object obj) + public override bool Equals(object? obj) { var localHeader = obj as TarHeader; @@ -690,7 +584,7 @@ public override bool Equals(object obj) if (localHeader != null) { result = (name == localHeader.name) - && (mode == localHeader.mode) + && (Mode == localHeader.Mode) && (UserId == localHeader.UserId) && (GroupId == localHeader.GroupId) && (Size == localHeader.Size) @@ -719,7 +613,7 @@ public override bool Equals(object obj) /// Value to apply as a default for userName. /// Value to apply as a default for groupId. /// Value to apply as a default for groupName. - static internal void SetValueDefaults(int userId, string userName, int groupId, string groupName) + internal static void SetValueDefaults(int userId, string userName, int groupId, string groupName) { defaultUserId = userIdAsSet = userId; defaultUser = userNameAsSet = userName; @@ -727,7 +621,7 @@ static internal void SetValueDefaults(int userId, string userName, int groupId, defaultGroupName = groupNameAsSet = groupName; } - static internal void RestoreSetValues() + internal static void RestoreSetValues() { defaultUserId = userIdAsSet; defaultUser = userNameAsSet; @@ -737,7 +631,7 @@ static internal void RestoreSetValues() // Return value that may be stored in octal or binary. Length must exceed 8. // - static private long ParseBinaryOrOctal(byte[] header, int offset, int length) + private static long ParseBinaryOrOctal(byte[] header, int offset, int length) { if (header[offset] >= 0x80) { @@ -759,7 +653,7 @@ static private long ParseBinaryOrOctal(byte[] header, int offset, int length) /// The offset into the buffer from which to parse. /// The number of header bytes to parse. /// The long equivalent of the octal string. - static public long ParseOctal(byte[] header, int offset, int length) + public static long ParseOctal(byte[] header, int offset, int length) { if (header == null) { @@ -814,7 +708,7 @@ static public long ParseOctal(byte[] header, int offset, int length) /// The name parsed. /// [Obsolete("No Encoding for Name field is specified, any non-ASCII bytes will be discarded")] - static public StringBuilder ParseName(byte[] header, int offset, int length) + public static StringBuilder ParseName(byte[] header, int offset, int length) { return ParseName(header, offset, length, null); } @@ -837,7 +731,7 @@ static public StringBuilder ParseName(byte[] header, int offset, int length) /// /// The name parsed. /// - static public StringBuilder ParseName(byte[] header, int offset, int length, Encoding encoding) + public static StringBuilder ParseName(byte[] header, int offset, int length, Encoding? encoding) { if (header == null) { @@ -926,7 +820,7 @@ public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int b /// The number of characters/bytes to add /// name encoding, or null for ASCII only /// The next free index in the - public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length, Encoding encoding) + public static int GetNameBytes(string name, int nameOffset, byte[] buffer, int bufferOffset, int length, Encoding? encoding) { if (name == null) { @@ -1007,7 +901,7 @@ public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, in /// /// The index of the next free byte in the buffer /// - public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, int length, Encoding encoding) + public static int GetNameBytes(StringBuilder name, byte[] buffer, int offset, int length, Encoding? encoding) { if (name == null) { @@ -1046,7 +940,7 @@ public static int GetNameBytes(string name, byte[] buffer, int offset, int lengt /// The number of header bytes to add /// /// The index of the next free byte in the buffer - public static int GetNameBytes(string name, byte[] buffer, int offset, int length, Encoding encoding) + public static int GetNameBytes(string name, byte[] buffer, int offset, int length, Encoding? encoding) { if (name == null) { @@ -1085,7 +979,7 @@ public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int /// The number of ascii characters to add. /// String encoding, or null for ASCII only /// The next free index in the buffer. - public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int bufferOffset, int length, Encoding encoding) + public static int GetAsciiBytes(string toAdd, int nameOffset, byte[] buffer, int bufferOffset, int length, Encoding? encoding) { if (toAdd == null) { @@ -1272,38 +1166,30 @@ private static DateTime GetDateTimeFromCTime(long ticks) #region Instance Fields - private string name; - private int mode; - private int userId; - private int groupId; + private string name = string.Empty; private long size; private DateTime modTime; - private int checksum; - private bool isChecksumValid; - private byte typeFlag; - private string linkName; - private string magic; - private string version; + private string linkName = string.Empty; + private string magic = TMAGIC; + private string version = " "; private string userName; private string groupName; - private int devMajor; - private int devMinor; #endregion Instance Fields #region Class Fields // Values used during recursive operations. - static internal int userIdAsSet; + internal static int userIdAsSet; - static internal int groupIdAsSet; - static internal string userNameAsSet; - static internal string groupNameAsSet = "None"; + internal static int groupIdAsSet; + internal static string userNameAsSet = "user"; + internal static string groupNameAsSet = "None"; - static internal int defaultUserId; - static internal int defaultGroupId; - static internal string defaultGroupName = "None"; - static internal string defaultUser; + internal static int defaultUserId; + internal static int defaultGroupId; + internal static string defaultGroupName = "None"; + internal static string defaultUser = "user"; #endregion Class Fields } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs b/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs index f1a3622de..ad8c6df2e 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs @@ -28,7 +28,7 @@ public TarInputStream(Stream inputStream) /// /// stream to source data from /// The used for the Name fields, or null for ASCII only - public TarInputStream(Stream inputStream, Encoding nameEncoding) + public TarInputStream(Stream inputStream, Encoding? nameEncoding) : this(inputStream, TarBuffer.DefaultBlockFactor, nameEncoding) { } @@ -52,7 +52,7 @@ public TarInputStream(Stream inputStream, int blockFactor) /// stream to source data from /// block factor to apply to archive /// The used for the Name fields, or null for ASCII only - public TarInputStream(Stream inputStream, int blockFactor, Encoding nameEncoding) + public TarInputStream(Stream inputStream, int blockFactor, Encoding? nameEncoding) { this.inputStream = inputStream; tarBuffer = TarBuffer.CreateInputTarBuffer(inputStream, blockFactor); @@ -176,7 +176,7 @@ public override void SetLength(long value) /// The offset in the buffer of the frist byte to write. /// The number of bytes to write. /// Any access - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { throw new NotSupportedException("TarInputStream Write not supported"); } @@ -322,7 +322,7 @@ protected override void Dispose(bool disposing) /// Set the entry factory for this instance. /// /// The factory for creating new entries - public void SetEntryFactory(IEntryFactory factory) + public void SetEntryFactory(IEntryFactory? factory) { entryFactory = factory; } @@ -438,7 +438,7 @@ public void Reset() /// /// The next TarEntry in the archive, or null. /// - public TarEntry GetNextEntry() + public TarEntry? GetNextEntry() { if (hasHitEOF) { @@ -452,11 +452,7 @@ public TarEntry GetNextEntry() byte[] headerBuf = tarBuffer.ReadBlock(); - if (headerBuf == null) - { - hasHitEOF = true; - } - else if (TarBuffer.IsEndOfArchiveBlock(headerBuf)) + if (TarBuffer.IsEndOfArchiveBlock(headerBuf)) { hasHitEOF = true; @@ -485,7 +481,7 @@ public TarEntry GetNextEntry() this.entryOffset = 0; this.entrySize = header.Size; - StringBuilder longName = null; + StringBuilder? longName = null; if (header.TypeFlag == TarHeader.LF_GNU_LONGNAME) { @@ -556,7 +552,7 @@ public TarEntry GetNextEntry() header.TypeFlag != TarHeader.LF_SYMLINK && header.TypeFlag != TarHeader.LF_DIR) { - // Ignore things we dont understand completely for now + // Ignore things we don't understand completely for now SkipToNextEntry(); headerBuf = tarBuffer.ReadBlock(); } @@ -675,7 +671,7 @@ public interface IEntryFactory /// public class EntryFactoryAdapter : IEntryFactory { - Encoding nameEncoding; + Encoding? nameEncoding; /// /// Construct standard entry factory class with ASCII name encoding /// @@ -687,7 +683,7 @@ public EntryFactoryAdapter() /// Construct standard entry factory with name encoding /// /// The used for the Name fields, or null for ASCII only - public EntryFactoryAdapter(Encoding nameEncoding) + public EntryFactoryAdapter(Encoding? nameEncoding) { this.nameEncoding = nameEncoding; } @@ -742,7 +738,7 @@ public TarEntry CreateEntry(byte[] headerBuffer) /// /// Buffer used with calls to Read() /// - protected byte[] readBuffer; + protected byte[]? readBuffer; /// /// Working buffer @@ -752,19 +748,19 @@ public TarEntry CreateEntry(byte[] headerBuffer) /// /// Current entry being read /// - private TarEntry currentEntry; + private TarEntry? currentEntry; /// /// Factory used to create TarEntry or descendant class instance /// - protected IEntryFactory entryFactory; + protected IEntryFactory? entryFactory; /// /// Stream used as the source of input data. /// private readonly Stream inputStream; - private readonly Encoding encoding; + private readonly Encoding? encoding; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs b/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs index 7c52e6c7c..aca5db488 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarOutputStream.cs @@ -29,7 +29,7 @@ public TarOutputStream(Stream outputStream) /// /// stream to write to /// The used for the Name fields, or null for ASCII only - public TarOutputStream(Stream outputStream, Encoding nameEncoding) + public TarOutputStream(Stream outputStream, Encoding? nameEncoding) : this(outputStream, TarBuffer.DefaultBlockFactor, nameEncoding) { } @@ -60,7 +60,7 @@ public TarOutputStream(Stream outputStream, int blockFactor) /// stream to write to /// blocking factor /// The used for the Name fields, or null for ASCII only - public TarOutputStream(Stream outputStream, int blockFactor, Encoding nameEncoding) + public TarOutputStream(Stream outputStream, int blockFactor, Encoding? nameEncoding) { if (outputStream == null) { @@ -188,7 +188,7 @@ public override int ReadByte() /// The total number of bytes read, or zero if at the end of the stream. /// The number of bytes may be less than the count /// requested if data is not available. - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { return outputStream.Read(buffer, offset, count); } @@ -515,7 +515,7 @@ private void WriteEofBlock() /// /// name encoding /// - protected Encoding nameEncoding; + protected Encoding? nameEncoding; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs index 3dbe98c8d..e98d3e211 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Deflater.cs @@ -424,7 +424,7 @@ public int Deflate(byte[] output) /// /// If offset or length don't match the array length. /// - public int Deflate(byte[] output, int offset, int length) + public int Deflate(byte[]? output, int offset, int length) { int origLength = length; @@ -556,7 +556,7 @@ public void SetDictionary(byte[] dictionary) /// /// If SetInput () or Deflate() were already called or another dictionary was already set. /// - public void SetDictionary(byte[] dictionary, int index, int count) + public void SetDictionary(byte[]? dictionary, int index, int count) { if (state != INIT_STATE) { diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs index 556911c40..c72e10e02 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterEngine.cs @@ -82,7 +82,7 @@ public DeflaterEngine(DeflaterPending pending, bool noAdlerCalculation) this.pending = pending; huffman = new DeflaterHuffman(pending); if (!noAdlerCalculation) - adler = new Adler32(); + adler.Reset(); window = new byte[2 * DeflaterConstants.WSIZE]; head = new short[DeflaterConstants.HASH_SIZE]; @@ -195,7 +195,7 @@ public bool NeedsInput() /// The buffer containing the dictionary data /// The offset in the buffer for the first byte of data /// The length of the dictionary data. - public void SetDictionary(byte[] buffer, int offset, int length) + public void SetDictionary(byte[]? buffer, int offset, int length) { #if DebugDeflation if (DeflaterConstants.DEBUGGING && (strstart != 1) ) @@ -916,7 +916,7 @@ private bool DeflateSlow(bool flush, bool finish) /// /// The input data for compression. /// - private byte[] inputBuf; + private byte[]? inputBuf; /// /// The total bytes of input read. @@ -939,7 +939,7 @@ private bool DeflateSlow(bool flush, bool finish) /// /// The adler checksum /// - private Adler32 adler; + private Adler32 adler = new Adler32(); #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs index 2f71366fc..bf5b5537b 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs @@ -1,4 +1,5 @@ using System; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip.Compression { @@ -66,13 +67,13 @@ private class Tree public short[] freqs; - public byte[] length; + public byte[] length = EmptyRefs.ByteArray; public int minNumCodes; public int numCodes; - private short[] codes; + private short[] codes = EmptyRefs.Int16Array; private readonly int[] bl_counts; private readonly int maxLength; private DeflaterHuffman dh; @@ -101,8 +102,8 @@ public void Reset() { freqs[i] = 0; } - codes = null; - length = null; + codes = EmptyRefs.Int16Array; + length = EmptyRefs.ByteArray; } public void WriteSymbol(int code) @@ -763,7 +764,7 @@ public void CompressBlock() /// Index of first byte to write /// Count of bytes to write /// True if this is the last block - public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock) + public void FlushStoredBlock(byte[]? stored, int storedOffset, int storedLength, bool lastBlock) { #if DebugDeflation // if (DeflaterConstants.DEBUGGING) { @@ -785,7 +786,7 @@ public void FlushStoredBlock(byte[] stored, int storedOffset, int storedLength, /// Index of first byte to flush /// Count of bytes to flush /// True if this is the last block - public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock) + public void FlushBlock(byte[]? stored, int storedOffset, int storedLength, bool lastBlock) { literalTree.freqs[EOF_SYMBOL]++; diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs index 439b4c601..1226bc3ae 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Inflater.cs @@ -141,9 +141,9 @@ public class Inflater private readonly StreamManipulator input; private OutputWindow outputWindow; - private InflaterDynHeader dynHeader; - private InflaterHuffmanTree litlenTree, distTree; - private Adler32 adler; + private InflaterDynHeader? dynHeader; + private InflaterHuffmanTree? litlenTree, distTree; + private Adler32 adler = new Adler32(); #endregion Instance Fields @@ -172,8 +172,8 @@ public Inflater() : this(false) public Inflater(bool noHeader) { this.noHeader = noHeader; - if (!noHeader) - this.adler = new Adler32(); + if (!noHeader) adler.Reset(); + input = new StreamManipulator(); outputWindow = new OutputWindow(); mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER; @@ -290,7 +290,7 @@ private bool DecodeHuffman() { case DECODE_HUFFMAN: // This is the inner loop so it is optimized a bit - while (((symbol = litlenTree.GetSymbol(input)) & ~0xff) == 0) + while (((symbol = litlenTree!.GetSymbol(input)) & ~0xff) == 0) { outputWindow.Write(symbol); if (--free < 258) @@ -342,7 +342,7 @@ private bool DecodeHuffman() goto case DECODE_HUFFMAN_DIST; // fall through case DECODE_HUFFMAN_DIST: - symbol = distTree.GetSymbol(input); + symbol = distTree!.GetSymbol(input); if (symbol < 0) { return false; @@ -408,9 +408,9 @@ private bool DecodeChksum() neededBits -= 8; } - if ((int)adler?.Value != readAdler) + if ((int)adler.Value != readAdler) { - throw new SharpZipBaseException("Adler chksum doesn't match: " + (int)adler?.Value + " vs. " + readAdler); + throw new SharpZipBaseException($"Calculated Adler checksum {adler.Value:x} does not match read checksum {readAdler:x}"); } mode = FINISHED; @@ -527,7 +527,7 @@ private bool Decode() } case DECODE_DYN_HEADER: - if (!dynHeader.AttemptRead()) + if (!dynHeader!.AttemptRead()) { return false; } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs index 8e0196b11..90aa5d79e 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterDynHeader.cs @@ -141,8 +141,8 @@ public InflaterHuffmanTree DistanceTree private byte[] codeLengths = new byte[CODELEN_MAX]; - private InflaterHuffmanTree litLenTree; - private InflaterHuffmanTree distTree; + private InflaterHuffmanTree? litLenTree; + private InflaterHuffmanTree? distTree; private int litLenCodeCount, distanceCodeCount, metaCodeCount; diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs index ed318824f..d87d8a0de 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/InflaterHuffmanTree.cs @@ -79,12 +79,12 @@ static InflaterHuffmanTree() /// public InflaterHuffmanTree(IList codeLengths) { - BuildTree(codeLengths); + tree = BuildTree(codeLengths); } #endregion Constructors - private void BuildTree(IList codeLengths) + private short[] BuildTree(IList codeLengths) { int[] blCount = new int[MAX_BITLEN + 1]; int[] nextCode = new int[MAX_BITLEN + 1]; @@ -122,7 +122,7 @@ private void BuildTree(IList codeLengths) /* Now create and fill the extra tables from longest to shortest * bit len. This way the sub trees will be aligned. */ - tree = new short[treeSize]; + var tree = new short[treeSize]; int treePtr = 512; for (int bits = MAX_BITLEN; bits >= 10; bits--) { @@ -166,6 +166,8 @@ private void BuildTree(IList codeLengths) } nextCode[bits] = code + (1 << (16 - bits)); } + + return tree; } /// diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs index 6ed7e4ab8..51dbc89aa 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/PendingBuffer.cs @@ -114,7 +114,7 @@ public void WriteInt(int value) /// data to write /// offset of first byte to write /// number of bytes to write - public void WriteBlock(byte[] block, int offset, int length) + public void WriteBlock(byte[]? block, int offset, int length) { #if DebugDeflation if (DeflaterConstants.DEBUGGING && (start != 0) ) @@ -223,7 +223,7 @@ public bool IsFlushed /// The offset into output array. /// The maximum number of bytes to store. /// The number of bytes flushed. - public int Flush(byte[] output, int offset, int length) + public int Flush(byte[]? output, int offset, int length) { if (bitCount >= 8) { diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs index 03cac7358..862c6dcfb 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/DeflaterOutputStream.cs @@ -153,20 +153,20 @@ public bool CanPatchEntries #region Encryption - private string password; + private string? password; - private ICryptoTransform cryptoTransform_; + private ICryptoTransform? cryptoTransform_; /// /// Returns the 10 byte AUTH CODE to be appended immediately following the AES data stream. /// - protected byte[] AESAuthCode; + protected byte[]? AESAuthCode; /// /// Get/set the password used for encryption. /// /// When set to null or if the password is empty no encryption is performed - public string Password + public string? Password { get { @@ -197,16 +197,16 @@ public string Password /// /// Number of bytes in buffer to encrypt /// - protected void EncryptBlock(byte[] buffer, int offset, int length) + protected void EncryptBlock(byte[]? buffer, int offset, int length) { - cryptoTransform_.TransformBlock(buffer, 0, length, buffer, 0); + cryptoTransform_?.TransformBlock(buffer, 0, length, buffer, 0); } /// /// Initializes encryption keys based on given . /// /// The password. - protected void InitializePassword(string password) + protected void InitializePassword(string? password) { var pkManaged = new PkzipClassicManaged(); byte[] key = PkzipClassic.GenerateKeys(ZipStrings.ConvertToArray(password)); @@ -216,7 +216,7 @@ protected void InitializePassword(string password) /// /// Initializes encryption keys based on given password. /// - protected void InitializeAESPassword(ZipEntry entry, string rawPassword, + protected void InitializeAESPassword(ZipEntry entry, string? rawPassword, out byte[] salt, out byte[] pwdVerifier) { salt = new byte[entry.AESSaltLen]; @@ -373,7 +373,7 @@ public override int ReadByte() /// The maximum number of bytes to read. /// The actual number of bytes read. Zero if end of stream is detected. /// Any access - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { throw new NotSupportedException("DeflaterOutputStream Read not supported"); } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs index 3fb257906..7d59c8e53 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/InflaterInputStream.cs @@ -156,7 +156,7 @@ public int ReadRawBuffer(byte[] buffer) /// The offset to start reading data into. /// The number of bytes to read. /// Returns the number of bytes read. - public int ReadRawBuffer(byte[] outBuffer, int offset, int length) + public int ReadRawBuffer(byte[]? outBuffer, int offset, int length) { if (length < 0) { @@ -192,7 +192,7 @@ public int ReadRawBuffer(byte[] outBuffer, int offset, int length) /// The offset to start adding data at. /// The number of bytes to read. /// Returns the number of bytes actually read. - public int ReadClearTextBuffer(byte[] outBuffer, int offset, int length) + public int ReadClearTextBuffer(byte[]? outBuffer, int offset, int length) { if (length < 0) { @@ -272,7 +272,7 @@ public long ReadLeLong() /// Get/set the to apply to any data. /// /// Set this value to null to have no transform applied. - public ICryptoTransform CryptoTransform + public ICryptoTransform? CryptoTransform { set { @@ -308,11 +308,11 @@ public ICryptoTransform CryptoTransform private int clearTextLength; private byte[] clearText; - private byte[] internalClearText; + private byte[]? internalClearText; private int available; - private ICryptoTransform cryptoTransform; + private ICryptoTransform? cryptoTransform; private Stream inputStream; #endregion Instance Fields @@ -600,7 +600,7 @@ public override void SetLength(long value) /// The offset of the first byte to write. /// The number of bytes to write. /// Any access - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { throw new NotSupportedException("InflaterInputStream Write not supported"); } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs index d8241c18c..a353882e0 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/OutputWindow.cs @@ -179,7 +179,7 @@ public int GetAvailable() /// /// If a window underflow occurs /// - public int CopyOutput(byte[] output, int offset, int len) + public int CopyOutput(byte[]? output, int offset, int len) { int copyEnd = windowEnd; if (len > windowFilled) diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs index aff6a9c6c..e7069b595 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs @@ -1,4 +1,5 @@ using System; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip.Compression.Streams { @@ -286,7 +287,7 @@ public void SetInput(byte[] buffer, int offset, int count) #region Instance Fields - private byte[] window_; + private byte[] window_ = EmptyRefs.ByteArray; private int windowStart_; private int windowEnd_; diff --git a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs index 71a739600..65d9fdc63 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/FastZip.cs @@ -14,32 +14,32 @@ public class FastZipEvents /// /// Delegate to invoke when processing directories. /// - public event EventHandler ProcessDirectory; + public event EventHandler? ProcessDirectory; /// /// Delegate to invoke when processing files. /// - public ProcessFileHandler ProcessFile; + public ProcessFileHandler? ProcessFile; /// /// Delegate to invoke during processing of files. /// - public ProgressHandler Progress; + public ProgressHandler? Progress; /// /// Delegate to invoke when processing for a file has been completed. /// - public CompletedFileHandler CompletedFile; + public CompletedFileHandler? CompletedFile; /// /// Delegate to invoke when processing directory failures. /// - public DirectoryFailureHandler DirectoryFailure; + public DirectoryFailureHandler? DirectoryFailure; /// /// Delegate to invoke when processing file failures. /// - public FileFailureHandler FileFailure; + public FileFailureHandler? FileFailure; /// /// Raise the directory failure event. @@ -47,18 +47,13 @@ public class FastZipEvents /// The directory causing the failure. /// The exception for this event. /// A boolean indicating if execution should continue or not. - public bool OnDirectoryFailure(string directory, Exception e) + public bool OnDirectoryFailure(string? directory, Exception? e) { - bool result = false; - DirectoryFailureHandler handler = DirectoryFailure; + if (DirectoryFailure is null) return false; - if (handler != null) - { - var args = new ScanFailureEventArgs(directory, e); - handler(this, args); - result = args.ContinueRunning; - } - return result; + var args = new ScanFailureEventArgs(directory, e); + DirectoryFailure(this, args); + return args.ContinueRunning; } /// @@ -67,18 +62,13 @@ public bool OnDirectoryFailure(string directory, Exception e) /// The file causing the failure. /// The exception for this failure. /// A boolean indicating if execution should continue or not. - public bool OnFileFailure(string file, Exception e) + public bool OnFileFailure(string? file, Exception? e) { - FileFailureHandler handler = FileFailure; - bool result = (handler != null); - - if (result) - { - var args = new ScanFailureEventArgs(file, e); - handler(this, args); - result = args.ContinueRunning; - } - return result; + if (FileFailure is null) return false; + + var args = new ScanFailureEventArgs(file, e); + FileFailure(this, args); + return args.ContinueRunning; } /// @@ -86,18 +76,13 @@ public bool OnFileFailure(string file, Exception e) /// /// The file being processed. /// A boolean indicating if execution should continue or not. - public bool OnProcessFile(string file) + public bool OnProcessFile(string? file) { - bool result = true; - ProcessFileHandler handler = ProcessFile; + if (ProcessFile is null) return false; - if (handler != null) - { - var args = new ScanEventArgs(file); - handler(this, args); - result = args.ContinueRunning; - } - return result; + var args = new ScanEventArgs(file); + ProcessFile(this, args); + return args.ContinueRunning; } /// @@ -105,17 +90,13 @@ public bool OnProcessFile(string file) /// /// The file whose processing has been completed. /// A boolean indicating if execution should continue or not. - public bool OnCompletedFile(string file) + public bool OnCompletedFile(string? file) { - bool result = true; - CompletedFileHandler handler = CompletedFile; - if (handler != null) - { - var args = new ScanEventArgs(file); - handler(this, args); - result = args.ContinueRunning; - } - return result; + if (CompletedFile is null) return false; + + var args = new ScanEventArgs(file); + CompletedFile(this, args); + return args.ContinueRunning; } /// @@ -124,17 +105,13 @@ public bool OnCompletedFile(string file) /// The directory being processed. /// Flag indicating if the directory has matching files as determined by the current filter. /// A of true if the operation should continue; false otherwise. - public bool OnProcessDirectory(string directory, bool hasMatchingFiles) + public bool OnProcessDirectory(string? directory, bool hasMatchingFiles) { - bool result = true; - EventHandler handler = ProcessDirectory; - if (handler != null) - { - var args = new DirectoryEventArgs(directory, hasMatchingFiles); - handler(this, args); - result = args.ContinueRunning; - } - return result; + if (ProcessDirectory is null) return false; + + var args = new DirectoryEventArgs(directory, hasMatchingFiles); + ProcessDirectory(this, args); + return args.ContinueRunning; } /// @@ -199,7 +176,7 @@ public FastZip() /// Initialise a new instance of /// /// The events to use during operations. - public FastZip(FastZipEvents events) + public FastZip(FastZipEvents? events) { events_ = events; } @@ -220,7 +197,7 @@ public bool CreateEmptyDirectories /// /// Get / set the password value. /// - public string Password + public string? Password { get { return password_; } set { password_ = value; } @@ -319,7 +296,7 @@ public Deflater.CompressionLevel CompressionLevel /// /// Delegate called when confirming overwriting of files. /// - public delegate bool ConfirmOverwriteDelegate(string fileName); + public delegate bool ConfirmOverwriteDelegate(string? fileName); #endregion Delegates @@ -333,8 +310,8 @@ public Deflater.CompressionLevel CompressionLevel /// True to recurse directories, false for no recursion. /// The file filter to apply. /// The directory filter to apply. - public void CreateZip(string zipFileName, string sourceDirectory, - bool recurse, string fileFilter, string directoryFilter) + public void CreateZip(string? zipFileName, string? sourceDirectory, + bool recurse, string? fileFilter, string? directoryFilter) { CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, directoryFilter); } @@ -346,7 +323,7 @@ public void CreateZip(string zipFileName, string sourceDirectory, /// The directory to obtain files and directories from. /// True to recurse directories, false for no recursion. /// The file filter to apply. - public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, string fileFilter) + public void CreateZip(string? zipFileName, string? sourceDirectory, bool recurse, string? fileFilter) { CreateZip(File.Create(zipFileName), sourceDirectory, recurse, fileFilter, null); } @@ -360,7 +337,7 @@ public void CreateZip(string zipFileName, string sourceDirectory, bool recurse, /// The file filter to apply. /// The directory filter to apply. /// The is closed after creation. - public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, string fileFilter, string directoryFilter) + public void CreateZip(Stream outputStream, string? sourceDirectory, bool recurse, string? fileFilter, string? directoryFilter) { NameTransform = new ZipNameTransform(sourceDirectory); sourceDirectory_ = sourceDirectory; @@ -409,7 +386,7 @@ public void CreateZip(Stream outputStream, string sourceDirectory, bool recurse, /// The zip file to extract from. /// The directory to save extracted information in. /// A filter to apply to files. - public void ExtractZip(string zipFileName, string targetDirectory, string fileFilter) + public void ExtractZip(string? zipFileName, string? targetDirectory, string? fileFilter) { ExtractZip(zipFileName, targetDirectory, Overwrite.Always, null, fileFilter, null, restoreDateTimeOnExtract_); } @@ -425,9 +402,9 @@ public void ExtractZip(string zipFileName, string targetDirectory, string fileFi /// A filter to apply to directories. /// Flag indicating whether to restore the date and time for extracted files. /// Allow parent directory traversal in file paths (e.g. ../file) - public void ExtractZip(string zipFileName, string targetDirectory, - Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate, - string fileFilter, string directoryFilter, bool restoreDateTime, bool allowParentTraversal = false) + public void ExtractZip(string? zipFileName, string? targetDirectory, + Overwrite overwrite, ConfirmOverwriteDelegate? confirmDelegate, + string? fileFilter, string? directoryFilter, bool restoreDateTime, bool allowParentTraversal = false) { Stream inputStream = File.Open(zipFileName, FileMode.Open, FileAccess.Read, FileShare.Read); ExtractZip(inputStream, targetDirectory, overwrite, confirmDelegate, fileFilter, directoryFilter, restoreDateTime, true, allowParentTraversal); @@ -445,9 +422,9 @@ public void ExtractZip(string zipFileName, string targetDirectory, /// Flag indicating whether to restore the date and time for extracted files. /// Flag indicating whether the inputStream will be closed by this method. /// Allow parent directory traversal in file paths (e.g. ../file) - public void ExtractZip(Stream inputStream, string targetDirectory, - Overwrite overwrite, ConfirmOverwriteDelegate confirmDelegate, - string fileFilter, string directoryFilter, bool restoreDateTime, + public void ExtractZip(Stream inputStream, string? targetDirectory, + Overwrite overwrite, ConfirmOverwriteDelegate? confirmDelegate, + string? fileFilter, string? directoryFilter, bool restoreDateTime, bool isStreamOwner, bool allowParentTraversal = false) { if ((overwrite == Overwrite.Prompt) && (confirmDelegate == null)) @@ -502,73 +479,56 @@ public void ExtractZip(Stream inputStream, string targetDirectory, #region Internal Processing - private void ProcessDirectory(object sender, DirectoryEventArgs e) + private void ProcessDirectory(object? sender, DirectoryEventArgs e) { - if (!e.HasMatchingFiles && CreateEmptyDirectories) - { - if (events_ != null) - { - events_.OnProcessDirectory(e.Name, e.HasMatchingFiles); - } + if (e.HasMatchingFiles || !CreateEmptyDirectories) return; - if (e.ContinueRunning) - { - if (e.Name != sourceDirectory_) - { - ZipEntry entry = entryFactory_.MakeDirectoryEntry(e.Name); - outputStream_.PutNextEntry(entry); - } - } - } + events_?.OnProcessDirectory(e.Name, e.HasMatchingFiles); + + if (!e.ContinueRunning || e.Name == sourceDirectory_) return; + + ZipEntry entry = entryFactory_.MakeDirectoryEntry(e.Name); + outputStream_?.PutNextEntry(entry); } - private void ProcessFile(object sender, ScanEventArgs e) + private void ProcessFile(object? sender, ScanEventArgs e) { - if ((events_ != null) && (events_.ProcessFile != null)) + events_?.ProcessFile?.Invoke(sender, e); + + if (!e.ContinueRunning) return; + + try { - events_.ProcessFile(sender, e); + // The open below is equivalent to OpenRead which guarantees that if opened the + // file will not be changed by subsequent openers, but precludes opening in some cases + // were it could succeed. ie the open may fail as its already open for writing and the share mode should reflect that. + using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + ZipEntry entry = entryFactory_.MakeFileEntry(e.Name); + outputStream_?.PutNextEntry(entry); + AddFileContents(e.Name, stream); + } } - - if (e.ContinueRunning) + catch (Exception ex) { - try + if (events_ != null) { - // The open below is equivalent to OpenRead which guarantees that if opened the - // file will not be changed by subsequent openers, but precludes opening in some cases - // were it could succeed. ie the open may fail as its already open for writing and the share mode should reflect that. - using (FileStream stream = File.Open(e.Name, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - ZipEntry entry = entryFactory_.MakeFileEntry(e.Name); - outputStream_.PutNextEntry(entry); - AddFileContents(e.Name, stream); - } + continueRunning_ = events_.OnFileFailure(e.Name, ex); } - catch (Exception ex) + else { - if (events_ != null) - { - continueRunning_ = events_.OnFileFailure(e.Name, ex); - } - else - { - continueRunning_ = false; - throw; - } + continueRunning_ = false; + throw; } } } - private void AddFileContents(string name, Stream stream) + private void AddFileContents(string? name, Stream stream) { - if (stream == null) - { - throw new ArgumentNullException(nameof(stream)); - } + if (stream == null) throw new ArgumentNullException(nameof(stream)); + if (outputStream_ is null) throw new InvalidOperationException("Output Stream is null"); - if (buffer_ == null) - { - buffer_ = new byte[4096]; - } + buffer_ ??= new byte[4096]; if ((events_ != null) && (events_.Progress != null)) { @@ -586,8 +546,10 @@ private void AddFileContents(string name, Stream stream) } } - private void ExtractFileEntry(ZipEntry entry, string targetName) + private void ExtractFileEntry(ZipEntry entry, string? targetName) { + if(zipFile_ is null) throw new InvalidOperationException("ZipFile is null"); + bool proceed = true; if (overwrite_ != Overwrite.Always) { @@ -617,11 +579,8 @@ private void ExtractFileEntry(ZipEntry entry, string targetName) { using (FileStream outputStream = File.Create(targetName)) { - if (buffer_ == null) - { - buffer_ = new byte[4096]; - } - if ((events_ != null) && (events_.Progress != null)) + buffer_ ??= new byte[4096]; + if (events_?.Progress != null) { StreamUtils.Copy(zipFile_.GetInputStream(entry), outputStream, buffer_, events_.Progress, events_.ProgressInterval, this, entry.Name, entry.Size); @@ -671,7 +630,7 @@ private void ExtractEntry(ZipEntry entry) bool doExtraction = entry.IsCompressionMethodSupported(); string targetName = entry.Name; - if (doExtraction) + if (doExtraction && extractNameTransform_ is {}) { if (entry.IsFile) { @@ -681,13 +640,13 @@ private void ExtractEntry(ZipEntry entry) { targetName = extractNameTransform_.TransformDirectory(targetName); } - - doExtraction = !(string.IsNullOrEmpty(targetName)); } + doExtraction = doExtraction && !string.IsNullOrEmpty(targetName); + // TODO: Fire delegate/throw exception were compression method not supported, or name is invalid? - string dirName = null; + string? dirName = null; if (doExtraction) { @@ -719,14 +678,9 @@ private void ExtractEntry(ZipEntry entry) doExtraction = false; if (events_ != null) { - if (entry.IsDirectory) - { - continueRunning_ = events_.OnDirectoryFailure(targetName, ex); - } - else - { - continueRunning_ = events_.OnFileFailure(targetName, ex); - } + continueRunning_ = entry.IsDirectory + ? events_.OnDirectoryFailure(targetName, ex) + : events_.OnFileFailure(targetName, ex); } else { @@ -759,25 +713,25 @@ private static bool NameIsValid(string name) #region Instance Fields private bool continueRunning_; - private byte[] buffer_; - private ZipOutputStream outputStream_; - private ZipFile zipFile_; - private string sourceDirectory_; - private NameFilter fileFilter_; - private NameFilter directoryFilter_; + private byte[]? buffer_; + private ZipOutputStream? outputStream_; + private ZipFile? zipFile_; + private string? sourceDirectory_; + private NameFilter? fileFilter_; + private NameFilter? directoryFilter_; private Overwrite overwrite_; - private ConfirmOverwriteDelegate confirmDelegate_; + private ConfirmOverwriteDelegate? confirmDelegate_; private bool restoreDateTimeOnExtract_; private bool restoreAttributesOnExtract_; private bool createEmptyDirectories_; - private FastZipEvents events_; + private FastZipEvents? events_; private IEntryFactory entryFactory_ = new ZipEntryFactory(); - private INameTransform extractNameTransform_; + private INameTransform? extractNameTransform_; private UseZip64 useZip64_ = UseZip64.Dynamic; private CompressionLevel compressionLevel_ = CompressionLevel.DEFAULT_COMPRESSION; - private string password_; + private string? password_; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/IEntryFactory.cs b/src/ICSharpCode.SharpZipLib/Zip/IEntryFactory.cs index bbe40c4d7..d1fd49a0e 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/IEntryFactory.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/IEntryFactory.cs @@ -12,7 +12,7 @@ public interface IEntryFactory /// /// The name of the file to create an entry for. /// Returns a file entry based on the passed. - ZipEntry MakeFileEntry(string fileName); + ZipEntry MakeFileEntry(string? fileName); /// /// Create a for a file given its name @@ -20,7 +20,7 @@ public interface IEntryFactory /// The name of the file to create an entry for. /// If true get details from the file system if the file exists. /// Returns a file entry based on the passed. - ZipEntry MakeFileEntry(string fileName, bool useFileSystem); + ZipEntry MakeFileEntry(string? fileName, bool useFileSystem); /// /// Create a for a file given its actual name and optional override name @@ -29,14 +29,14 @@ public interface IEntryFactory /// An alternative name to be used for the new entry. Null if not applicable. /// If true get details from the file system if the file exists. /// Returns a file entry based on the passed. - ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSystem); + ZipEntry MakeFileEntry(string? fileName, string? entryName, bool useFileSystem); /// /// Create a for a directory given its name /// /// The name of the directory to create an entry for. /// Returns a directory entry based on the passed. - ZipEntry MakeDirectoryEntry(string directoryName); + ZipEntry MakeDirectoryEntry(string? directoryName); /// /// Create a for a directory given its name @@ -44,7 +44,7 @@ public interface IEntryFactory /// The name of the directory to create an entry for. /// If true get details from the file system for this directory if it exists. /// Returns a directory entry based on the passed. - ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem); + ZipEntry MakeDirectoryEntry(string? directoryName, bool useFileSystem); /// /// Get/set the applicable. diff --git a/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs b/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs index c10f5ceab..054cf2354 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/WindowsNameTransform.cs @@ -16,7 +16,7 @@ public class WindowsNameTransform : INameTransform /// This may not valid for all windows systems - CE?, etc but I cant find the equivalent in the CLR. private const int MaxPath = 260; - private string _baseDirectory; + private string? _baseDirectory; private bool _trimIncomingPaths; private char _replacementChar = '_'; private bool _allowParentTraversal; @@ -40,7 +40,7 @@ public class WindowsNameTransform : INameTransform /// /// /// Allow parent directory traversal in file paths (e.g. ../file) - public WindowsNameTransform(string baseDirectory, bool allowParentTraversal = false) + public WindowsNameTransform(string? baseDirectory, bool allowParentTraversal = false) { BaseDirectory = baseDirectory ?? throw new ArgumentNullException(nameof(baseDirectory), "Directory name is invalid"); AllowParentTraversal = allowParentTraversal; @@ -57,7 +57,7 @@ public WindowsNameTransform() /// /// Gets or sets a value containing the target directory to prefix values with. /// - public string BaseDirectory + public string? BaseDirectory { get { return _baseDirectory; } set @@ -94,7 +94,7 @@ public bool TrimIncomingPaths /// /// The directory name to transform. /// The transformed name. - public string TransformDirectory(string name) + public string TransformDirectory(string? name) { name = TransformFile(name); if (name.Length > 0) @@ -116,7 +116,7 @@ public string TransformDirectory(string name) /// /// The file name to transform. /// The transformed name. - public string TransformFile(string name) + public string TransformFile(string? name) { if (name != null) { @@ -152,7 +152,7 @@ public string TransformFile(string name) /// The name to test. /// Returns true if the name is a valid zip name; false otherwise. /// The filename isnt a true windows path in some fundamental ways like no absolute paths, no rooted paths etc. - public static bool IsValidName(string name) + public static bool IsValidName(string? name) { bool result = (name != null) && diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs index cc2fd27d2..169c86ebf 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipConstants.cs @@ -481,17 +481,17 @@ public static int DefaultCodePage /// Deprecated wrapper for [Obsolete("Use ZipStrings.ConvertToString instead")] - public static string ConvertToString(byte[] data, int count) + public static string ConvertToString(byte[]? data, int count) => ZipStrings.ConvertToString(data, count); /// Deprecated wrapper for [Obsolete("Use ZipStrings.ConvertToString instead")] - public static string ConvertToString(byte[] data) + public static string ConvertToString(byte[]? data) => ZipStrings.ConvertToString(data); /// Deprecated wrapper for [Obsolete("Use ZipStrings.ConvertToStringExt instead")] - public static string ConvertToStringExt(int flags, byte[] data, int count) + public static string ConvertToStringExt(int flags, byte[]? data, int count) => ZipStrings.ConvertToStringExt(flags, data, count); /// Deprecated wrapper for @@ -499,14 +499,14 @@ public static string ConvertToStringExt(int flags, byte[] data, int count) public static string ConvertToStringExt(int flags, byte[] data) => ZipStrings.ConvertToStringExt(flags, data); - /// Deprecated wrapper for + /// Deprecated wrapper for [Obsolete("Use ZipStrings.ConvertToArray instead")] - public static byte[] ConvertToArray(string str) + public static byte[] ConvertToArray(string? str) => ZipStrings.ConvertToArray(str); - /// Deprecated wrapper for + /// Deprecated wrapper for [Obsolete("Use ZipStrings.ConvertToArray instead")] - public static byte[] ConvertToArray(int flags, string str) + public static byte[] ConvertToArray(int flags, string? str) => ZipStrings.ConvertToArray(flags, str); } } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs index 7d15b01d2..d7d4aa199 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntry.cs @@ -160,7 +160,7 @@ public ZipEntry(string name) /// /// The name for this entry. Can include directory components. /// The convention for names is 'unix' style paths with no device names and - /// path elements separated by '/' characters. This is not enforced see CleanName + /// path elements separated by '/' characters. This is not enforced see CleanName /// on how to ensure names are valid if this is desired. /// /// @@ -774,7 +774,7 @@ public DateTime DateTime /// The unix naming convention is followed. /// Path components in the entry should always separated by forward slashes ('/'). /// Dos device names like C: should also be removed. - /// See the class, or + /// See the class, or /// public string Name { @@ -897,7 +897,7 @@ internal CompressionMethod CompressionMethodForHeader /// /// Extra data or null if not set. /// - public byte[] ExtraData + public byte[]? ExtraData { get { @@ -1106,7 +1106,7 @@ internal void ProcessExtraData(bool localHeader) #endif // Check for Unix timestamp - ExtendedUnixData unixData = extraData.GetData(); + ExtendedUnixData? unixData = extraData.GetData(); if (unixData != null && unixData.Include.HasFlag(ExtendedUnixData.Flags.ModificationTime)) return unixData.ModificationTime; @@ -1152,7 +1152,7 @@ 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. /// - public string Comment + public string? Comment { get { @@ -1280,7 +1280,7 @@ public static bool IsCompressionMethodSupported(CompressionMethod method) /// /// The Zip name transform class is more flexible. /// - public static string CleanName(string name) + public static string CleanName(string? name) { if (name == null) { @@ -1319,8 +1319,8 @@ public static string CleanName(string name) private DateTime dateTime; private CompressionMethod method = CompressionMethod.Deflated; - private byte[] extra; - private string comment; + private byte[]? extra; + private string? comment; private int flags; // general purpose bit flags diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs index e82eafc48..6eddb5f04 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipEntryFactory.cs @@ -179,7 +179,7 @@ public bool IsUnicodeText /// /// The name of the file to create a new entry for. /// Returns a new based on the . - public ZipEntry MakeFileEntry(string fileName) + public ZipEntry MakeFileEntry(string? fileName) { return MakeFileEntry(fileName, null, true); } @@ -190,7 +190,7 @@ public ZipEntry MakeFileEntry(string fileName) /// The name of the file to create a new entry for. /// If true entry detail is retrieved from the file system if the file exists. /// Returns a new based on the . - public ZipEntry MakeFileEntry(string fileName, bool useFileSystem) + public ZipEntry MakeFileEntry(string? fileName, bool useFileSystem) { return MakeFileEntry(fileName, null, useFileSystem); } @@ -202,7 +202,7 @@ public ZipEntry MakeFileEntry(string fileName, bool useFileSystem) /// An alternative name to be used for the new entry. Null if not applicable. /// If true entry detail is retrieved from the file system if the file exists. /// Returns a new based on the . - public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSystem) + public ZipEntry MakeFileEntry(string? fileName, string? entryName, bool useFileSystem) { var result = new ZipEntry(nameTransform_.TransformFile(!string.IsNullOrEmpty(entryName) ? entryName : fileName)); result.IsUnicodeText = isUnicodeText_; @@ -210,7 +210,7 @@ public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSys int externalAttributes = 0; bool useAttributes = (setAttributes_ != 0); - FileInfo fi = null; + FileInfo? fi = null; if (useFileSystem) { fi = new FileInfo(fileName); @@ -279,7 +279,7 @@ public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSys /// /// The raw untransformed name for the new directory /// Returns a new representing a directory. - public ZipEntry MakeDirectoryEntry(string directoryName) + public ZipEntry MakeDirectoryEntry(string? directoryName) { return MakeDirectoryEntry(directoryName, true); } @@ -290,7 +290,7 @@ public ZipEntry MakeDirectoryEntry(string directoryName) /// The raw untransformed name for the new directory /// If true entry detail is retrieved from the file system if the file exists. /// Returns a new representing a directory. - public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) + public ZipEntry MakeDirectoryEntry(string? directoryName, bool useFileSystem) { var result = new ZipEntry(nameTransform_.TransformDirectory(directoryName)); result.IsUnicodeText = isUnicodeText_; @@ -298,7 +298,7 @@ public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) int externalAttributes = 0; - DirectoryInfo di = null; + DirectoryInfo? di = null; if (useFileSystem) { diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs index ef8142b65..e0b208f42 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs @@ -20,7 +20,7 @@ public ZipException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public ZipException(string message) + public ZipException(string? message) : base(message) { } @@ -30,7 +30,7 @@ public ZipException(string message) /// /// A that describes the error. /// The that caused this exception. - public ZipException(string message, Exception innerException) + public ZipException(string? message, Exception? innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public ZipException(string message, Exception innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected ZipException(SerializationInfo info, StreamingContext context) + protected ZipException(SerializationInfo? info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs index 0535b1250..65ae67266 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using ICSharpCode.SharpZipLib.Core; namespace ICSharpCode.SharpZipLib.Zip { @@ -28,7 +29,7 @@ public interface ITaggedData /// Get the data representing this instance. /// /// Returns the data for this instance. - byte[] GetData(); + byte[]? GetData(); } /// @@ -77,7 +78,7 @@ public void SetData(byte[] data, int offset, int count) /// Get the binary data representing this instance. /// /// The raw binary data representing this instance. - public byte[] GetData() + public byte[]? GetData() { return _data; } @@ -88,7 +89,7 @@ public byte[] GetData() /// Get /set the binary data representing this instance. /// /// The raw binary data representing this instance. - public byte[] Data + public byte[]? Data { get { return _data; } set { _data = value; } @@ -101,7 +102,7 @@ public byte[] Data /// private short _tag; - private byte[] _data; + private byte[]? _data; #endregion Instance Fields } @@ -149,7 +150,7 @@ public short TagID /// The raw data to extract values from. /// The index to start extracting values from. /// The number of bytes available. - public void SetData(byte[] data, int index, int count) + public void SetData(byte[]? data, int index, int count) { using (MemoryStream ms = new MemoryStream(data, index, count, false)) using (ZipHelperStream helperStream = new ZipHelperStream(ms)) @@ -338,7 +339,7 @@ public short TagID /// The raw data to extract values from. /// The index to start extracting values from. /// The number of bytes available. - public void SetData(byte[] data, int index, int count) + public void SetData(byte[]? data, int index, int count) { using (MemoryStream ms = new MemoryStream(data, index, count, false)) using (ZipHelperStream helperStream = new ZipHelperStream(ms)) @@ -487,7 +488,7 @@ internal interface ITaggedDataFactory /// The offset to begin extracting data from. /// The number of bytes to extract. /// The located value found, or null if not found. - ITaggedData Create(short tag, byte[] data, int offset, int count); + ITaggedData Create(short tag, byte[]? data, int offset, int count); } /// @@ -510,23 +511,15 @@ sealed public class ZipExtraData : IDisposable /// public ZipExtraData() { - Clear(); } /// /// Initialise with known extra data. /// /// The extra data. - public ZipExtraData(byte[] data) + public ZipExtraData(byte[]? data) { - if (data == null) - { - _data = new byte[0]; - } - else - { - _data = data; - } + _data = data ?? new byte[0]; } #endregion Constructors @@ -550,28 +543,25 @@ public byte[] GetEntryData() /// public void Clear() { - if ((_data == null) || (_data.Length != 0)) + if (_data.Length != 0) { - _data = new byte[0]; + _data = EmptyRefs.ByteArray; } } /// /// Gets the current extra data length. /// - public int Length - { - get { return _data.Length; } - } + public int Length => _data.Length; /// /// Get a read-only for the associated tag. /// /// The tag to locate data for. /// Returns a containing tag data or null if no tag was found. - public Stream GetStreamForTag(int tag) + public Stream? GetStreamForTag(int tag) { - Stream result = null; + Stream? result = null; if (Find(tag)) { result = new MemoryStream(_data, _index, _readValueLength, false); @@ -584,7 +574,7 @@ public Stream GetStreamForTag(int tag) /// /// The tag to search for. /// Returns a tagged value or null if none found. - public T GetData() + public T? GetData() where T : class, ITaggedData, new() { T result = new T(); @@ -600,10 +590,7 @@ public T GetData() /// Get the length of the last value found by /// /// This is only valid if has previously returned true. - public int ValueLength - { - get { return _readValueLength; } - } + public int ValueLength => _readValueLength; /// /// Get the index for the current read value. @@ -611,10 +598,7 @@ public int ValueLength /// This is only valid if has previously returned true. /// Initially the result will be the index of the first byte of actual data. The value is updated after calls to /// , and . - public int CurrentReadIndex - { - get { return _index; } - } + public int CurrentReadIndex => _index; /// /// Get the number of bytes remaining to be read for the current value; @@ -689,14 +673,14 @@ public void AddEntry(ITaggedData taggedData) /// The ID for this entry. /// The data to add. /// If the ID already exists its contents are replaced. - public void AddEntry(int headerID, byte[] fieldData) + public void AddEntry(int headerID, byte[]? fieldData) { if ((headerID > ushort.MaxValue) || (headerID < 0)) { throw new ArgumentOutOfRangeException(nameof(headerID)); } - int addLength = (fieldData == null) ? 0 : fieldData.Length; + int addLength = fieldData?.Length ?? 0; if (addLength > ushort.MaxValue) { @@ -724,10 +708,7 @@ public void AddEntry(int headerID, byte[] fieldData) _data = newData; SetShort(ref index, headerID); SetShort(ref index, addLength); - if (fieldData != null) - { - fieldData.CopyTo(newData, index); - } + fieldData?.CopyTo(newData, index); } /// @@ -747,7 +728,7 @@ public void StartNewEntry() /// The identifier to use for this entry. public void AddNewEntry(int headerID) { - byte[] newData = _newEntry.ToArray(); + byte[] newData = _newEntry?.ToArray() ?? EmptyRefs.ByteArray; _newEntry = null; AddEntry(headerID, newData); } @@ -759,6 +740,8 @@ public void AddNewEntry(int headerID) /// public void AddData(byte data) { + if(_newEntry is null) throw new InvalidOperationException("No pending entry"); + _newEntry.WriteByte(data); } @@ -769,10 +752,8 @@ public void AddData(byte data) /// public void AddData(byte[] data) { - if (data == null) - { - throw new ArgumentNullException(nameof(data)); - } + if (data == null) throw new ArgumentNullException(nameof(data)); + if(_newEntry is null) throw new InvalidOperationException("No pending entry"); _newEntry.Write(data, 0, data.Length); } @@ -784,10 +765,11 @@ public void AddData(byte[] data) /// public void AddLeShort(int toAdd) { + // Note: No null checking is performed here to improve performance unchecked { - _newEntry.WriteByte((byte)toAdd); - _newEntry.WriteByte((byte)(toAdd >> 8)); + _newEntry!.WriteByte((byte)toAdd); + _newEntry!.WriteByte((byte)(toAdd >> 8)); } } @@ -971,8 +953,8 @@ public void Dispose() private int _readValueStart; private int _readValueLength; - private MemoryStream _newEntry; - private byte[] _data; + private MemoryStream? _newEntry; + private byte[] _data = EmptyRefs.ByteArray; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs index c12a53df1..6352da6ec 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs @@ -25,7 +25,7 @@ public class KeysRequiredEventArgs : EventArgs /// Initialise a new instance of /// /// The name of the file for which keys are required. - public KeysRequiredEventArgs(string name) + public KeysRequiredEventArgs(string? name) { fileName = name; } @@ -35,7 +35,7 @@ public KeysRequiredEventArgs(string name) /// /// The name of the file for which keys are required. /// The current key value. - public KeysRequiredEventArgs(string name, byte[] keyValue) + public KeysRequiredEventArgs(string? name, byte[]? keyValue) { fileName = name; key = keyValue; @@ -48,7 +48,7 @@ public KeysRequiredEventArgs(string name, byte[] keyValue) /// /// Gets the name of the file for which keys are required. /// - public string FileName + public string? FileName { get { return fileName; } } @@ -56,7 +56,7 @@ public string FileName /// /// Gets or sets the key value /// - public byte[] Key + public byte[]? Key { get { return key; } set { key = value; } @@ -66,8 +66,8 @@ public byte[] Key #region Instance Fields - private readonly string fileName; - private byte[] key; + private readonly string? fileName; + private byte[]? key; #endregion Instance Fields } @@ -141,7 +141,7 @@ public class TestStatus /// Initialise a new instance of /// /// The this status applies to. - public TestStatus(ZipFile file) + public TestStatus(ZipFile? file) { file_ = file; } @@ -161,7 +161,7 @@ public TestOperation Operation /// /// Get the this status is applicable to. /// - public ZipFile File + public ZipFile? File { get { return file_; } } @@ -169,7 +169,7 @@ public ZipFile File /// /// Get the current/last entry tested. /// - public ZipEntry Entry + public ZipEntry? Entry { get { return entry_; } } @@ -213,7 +213,7 @@ internal void SetOperation(TestOperation operation) operation_ = operation; } - internal void SetEntry(ZipEntry entry) + internal void SetEntry(ZipEntry? entry) { entry_ = entry; entryValid_ = true; @@ -229,8 +229,8 @@ internal void SetBytesTested(long value) #region Instance Fields - private readonly ZipFile file_; - private ZipEntry entry_; + private readonly ZipFile? file_; + private ZipEntry? entry_; private bool entryValid_; private int errorCount_; private long bytesTested_; @@ -244,7 +244,7 @@ internal void SetBytesTested(long value) /// /// If the message is non-null an error has occured. If the message is null /// the operation as found in status has started. - public delegate void ZipTestResultHandler(TestStatus status, string message); + public delegate void ZipTestResultHandler(TestStatus? status, string? message); #endregion Test Definitions @@ -321,20 +321,20 @@ public class ZipFile : IEnumerable, IDisposable /// Delegate for handling keys/password setting during compression/decompression. /// public delegate void KeysRequiredEventHandler( - object sender, - KeysRequiredEventArgs e + object? sender, + KeysRequiredEventArgs? e ); /// /// Event handler for handling encryption keys. /// - public KeysRequiredEventHandler KeysRequired; + public KeysRequiredEventHandler? KeysRequired; /// /// Handles getting of encryption keys when required. /// /// The file for which encryption keys are required. - private void OnKeysRequired(string fileName) + private void OnKeysRequired(string? fileName) { if (KeysRequired != null) { @@ -347,7 +347,7 @@ private void OnKeysRequired(string fileName) /// /// Get/set the encryption key value. /// - private byte[] Key + private byte[]? Key { get { return key; } set { key = value; } @@ -547,10 +547,13 @@ public ZipFile(Stream stream, bool leaveOpen) /// /// Initialises a default instance with no entries and no file storage. /// - internal ZipFile() + internal ZipFile(bool newArchive, Stream baseStream, bool leaveOpen = false) { entries_ = new ZipEntry[0]; isNewArchive_ = true; + + baseStream_ = baseStream; + isStreamOwner = !leaveOpen; } #endregion Constructors @@ -597,11 +600,9 @@ public static ZipFile Create(string fileName) FileStream fs = File.Create(fileName); - return new ZipFile + return new ZipFile(true, fs, false) { name_ = fileName, - baseStream_ = fs, - isStreamOwner = true }; } @@ -629,11 +630,7 @@ public static ZipFile Create(Stream outStream) throw new ArgumentException("Stream is not seekable", nameof(outStream)); } - var result = new ZipFile - { - baseStream_ = outStream - }; - return result; + return new ZipFile(true, outStream); } #endregion Creators @@ -674,7 +671,7 @@ public bool IsNewArchive /// /// Gets the comment for the zip file. /// - public string ZipFileComment + public string? ZipFileComment { get { return comment_; } } @@ -682,7 +679,7 @@ public string ZipFileComment /// /// Gets the name of this zip file. /// - public string Name + public string? Name { get { return name_; } } @@ -755,7 +752,7 @@ public IEnumerator GetEnumerator() /// /// The Zip file has been closed. /// - public int FindEntry(string name, bool ignoreCase) + public int FindEntry(string? name, bool ignoreCase) { if (isDisposed_) { @@ -786,7 +783,7 @@ public int FindEntry(string name, bool ignoreCase) /// /// The Zip file has been closed. /// - public ZipEntry GetEntry(string name) + public ZipEntry? GetEntry(string? name) { if (isDisposed_) { @@ -913,7 +910,7 @@ public bool TestArchive(bool testData) /// The handler to call during testing. /// true if all tests pass, false otherwise /// The object has already been closed. - public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler resultHandler) + public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler? resultHandler) { if (isDisposed_) { @@ -1477,9 +1474,9 @@ public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataS // NOTE: the baseStream_ may not currently support writing or seeking. - updateIndex_ = new Dictionary(); + updateIndex_ = new Dictionary(); - updates_ = new List(entries_.Length); + updates_ = new List(entries_.Length); foreach (ZipEntry entry in entries_) { int index = updates_.Count; @@ -1491,14 +1488,17 @@ public void BeginUpdate(IArchiveStorage archiveStorage, IDynamicDataSource dataS updates_.Sort(new UpdateComparer()); int idx = 0; - foreach (ZipUpdate update in updates_) + foreach (var update in updates_) { //If last entry, there is no next entry offset to use if (idx == updates_.Count - 1) break; - update.OffsetBasedSize = ((ZipUpdate)updates_[idx + 1]).Entry.Offset - update.Entry.Offset; + if (!(update is {}) || !(updates_[idx + 1] is {} nextUpdate)) continue; + + update.OffsetBasedSize = nextUpdate.Entry.Offset - update.Entry.Offset; idx++; + } updateCount_ = updates_.Count; @@ -1544,14 +1544,13 @@ public void CommitUpdate() { if (isDisposed_) { - throw new ObjectDisposedException("ZipFile"); + throw new ObjectDisposedException(nameof(ZipFile)); } CheckUpdating(); try { - updateIndex_.Clear(); updateIndex_ = null; if (contentsEdited_) @@ -1565,14 +1564,11 @@ public void CommitUpdate() else { // Create an empty archive if none existed originally. - if (entries_.Length == 0) - { - byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_); - using (ZipHelperStream zhs = new ZipHelperStream(baseStream_)) - { - zhs.WriteEndOfCentralDirectory(0, 0, 0, theComment); - } - } + if (entries_.Length != 0) return; + + byte[] theComment = (newComment_ != null) ? newComment_.RawComment : ZipStrings.ConvertToArray(comment_); + using ZipHelperStream zhs = new ZipHelperStream(baseStream_); + zhs.WriteEndOfCentralDirectory(0, 0, 0, theComment); } } finally @@ -1596,7 +1592,7 @@ public void AbortUpdate() /// /// The comment to record. /// ZipFile has been closed. - public void SetComment(string comment) + public void SetComment(string? comment) { if (isDisposed_) { @@ -1624,6 +1620,8 @@ public void SetComment(string comment) private void AddUpdate(ZipUpdate update) { + if(updates_ is null || updateIndex_ is null) throw new InvalidOperationException("Archive updating has not been started"); + contentsEdited_ = true; int index = FindExistingUpdate(update.Entry.Name); @@ -1944,7 +1942,7 @@ public bool Delete(string fileName) throw new ArgumentNullException(nameof(fileName)); } - CheckUpdating(); + if (updates_ is null) throw new NotUpdatingException(); bool result = false; int index = FindExistingUpdate(fileName); @@ -1973,7 +1971,7 @@ public void Delete(ZipEntry entry) throw new ArgumentNullException(nameof(entry)); } - CheckUpdating(); + if (updates_ is null) throw new NotUpdatingException(); int index = FindExistingUpdate(entry); if (index >= 0) @@ -1996,8 +1994,8 @@ public void Delete(ZipEntry entry) private void WriteLEShort(int value) { - baseStream_.WriteByte((byte)(value & 0xff)); - baseStream_.WriteByte((byte)((value >> 8) & 0xff)); + baseStream_!.WriteByte((byte)(value & 0xff)); + baseStream_!.WriteByte((byte)((value >> 8) & 0xff)); } /// @@ -2005,8 +2003,8 @@ private void WriteLEShort(int value) /// private void WriteLEUshort(ushort value) { - baseStream_.WriteByte((byte)(value & 0xff)); - baseStream_.WriteByte((byte)(value >> 8)); + baseStream_!.WriteByte((byte)(value & 0xff)); + baseStream_!.WriteByte((byte)(value >> 8)); } /// @@ -2351,7 +2349,7 @@ private void PostUpdateCleanup() } } - private string GetTransformedFileName(string name) + private string? GetTransformedFileName(string? name) { INameTransform transform = NameTransform; return (transform != null) ? @@ -2359,7 +2357,7 @@ private string GetTransformedFileName(string name) name; } - private string GetTransformedDirectoryName(string name) + private string? GetTransformedDirectoryName(string? name) { INameTransform transform = NameTransform; return (transform != null) ? @@ -2555,10 +2553,12 @@ private void CopyEntryDataDirect(ZipUpdate update, Stream stream, bool updateCrc private int FindExistingUpdate(ZipEntry entry) { int result = -1; - string convertedName = entry.IsDirectory + string? convertedName = entry.IsDirectory ? GetTransformedDirectoryName(entry.Name) : GetTransformedFileName(entry.Name); + if (updateIndex_ is null) throw new NotUpdatingException(); + if (updateIndex_.ContainsKey(convertedName)) { result = (int)updateIndex_[convertedName]; @@ -2579,11 +2579,13 @@ private int FindExistingUpdate(ZipEntry entry) return result; } - private int FindExistingUpdate(string fileName) + private int FindExistingUpdate(string? fileName) { int result = -1; - string convertedName = GetTransformedFileName(fileName); + string? convertedName = GetTransformedFileName(fileName); + + if (updateIndex_ is null) throw new NotUpdatingException(); if (updateIndex_.ContainsKey(convertedName)) { @@ -2612,12 +2614,7 @@ private int FindExistingUpdate(string fileName) /// The output stream obtained for the entry. private Stream GetOutputStream(ZipEntry entry) { - Stream result = baseStream_; - - if (entry.IsCrypted == true) - { - result = CreateAndInitEncryptionStream(result, entry); - } + var result = entry.IsCrypted ? CreateAndInitEncryptionStream(baseStream_, entry) : baseStream_; switch (entry.CompressionMethod) { @@ -2641,16 +2638,11 @@ private Stream GetOutputStream(ZipEntry entry) private void AddEntry(ZipFile workFile, ZipUpdate update) { - Stream source = null; + Stream? source = null; if (update.Entry.IsFile) { - source = update.GetSource(); - - if (source == null) - { - source = updateDataSource_.GetSource(update.Entry, update.Filename); - } + source = update.GetSource() ?? updateDataSource_?.GetSource(update.Entry, update.Filename); } if (source != null) @@ -2790,7 +2782,7 @@ private void CopyEntry(ZipFile workFile, ZipUpdate update) CopyDescriptorBytes(update, workFile.baseStream_, baseStream_); } - private void Reopen(Stream source) + private void Reopen(Stream? source) { isNewArchive_ = false; baseStream_ = source ?? throw new ZipException("Failed to reopen archive - no source"); @@ -2809,9 +2801,11 @@ private void Reopen() private void UpdateCommentOnly() { + if(archiveStorage_ is null) throw new InvalidOperationException("Archive Storage is null"); + long baseLength = baseStream_.Length; - ZipHelperStream updateFile = null; + ZipHelperStream? updateFile = null; if (archiveStorage_.UpdateMode == FileUpdateMode.Safe) { @@ -2822,7 +2816,6 @@ private void UpdateCommentOnly() }; baseStream_.Dispose(); - baseStream_ = null; } else { @@ -2841,7 +2834,6 @@ private void UpdateCommentOnly() else { baseStream_.Dispose(); - baseStream_ = null; updateFile = new ZipHelperStream(Name); } } @@ -2859,7 +2851,7 @@ private void UpdateCommentOnly() const int CentralHeaderCommentSizeOffset = 16; updateFile.Position += CentralHeaderCommentSizeOffset; - byte[] rawComment = newComment_.RawComment; + byte[] rawComment = newComment_?.RawComment ?? EmptyRefs.ByteArray; updateFile.WriteLEShort(rawComment.Length); updateFile.Write(rawComment, 0, rawComment.Length); @@ -2879,7 +2871,7 @@ private void UpdateCommentOnly() /// /// Class used to sort updates. /// - private class UpdateComparer : IComparer + private class UpdateComparer : IComparer { /// /// Compares two objects and returns a value indicating whether one is @@ -2888,7 +2880,7 @@ private class UpdateComparer : IComparer /// First object to compare /// Second object to compare. /// Compare result. - public int Compare(ZipUpdate x, ZipUpdate y) + public int Compare(ZipUpdate? x, ZipUpdate? y) { int result; @@ -2943,18 +2935,21 @@ private void RunUpdates() ZipFile workFile; + if (updates_ is null) throw new NotUpdatingException(); + if (archiveStorage_ is null) throw new InvalidOperationException("Archive Storage is null"); + if (IsNewArchive) { workFile = this; - workFile.baseStream_.Position = 0; directUpdate = true; } else if (archiveStorage_.UpdateMode == FileUpdateMode.Direct) { + workFile = this; - workFile.baseStream_.Position = 0; directUpdate = true; + // Sort the updates by offset within copies/modifies, then adds. // This ensures that data required by copies will not be overwritten. updates_.Sort(new UpdateComparer()); @@ -2970,9 +2965,11 @@ private void RunUpdates() } } + workFile.baseStream_.Position = 0; + try { - foreach (ZipUpdate update in updates_) + foreach (ZipUpdate? update in updates_) { if (update != null) { @@ -3018,7 +3015,7 @@ private void RunUpdates() long centralDirOffset = workFile.baseStream_.Position; - foreach (ZipUpdate update in updates_) + foreach (ZipUpdate? update in updates_) { if (update != null) { @@ -3035,7 +3032,7 @@ private void RunUpdates() endOfStream = workFile.baseStream_.Position; // And now patch entries... - foreach (ZipUpdate update in updates_) + foreach (ZipUpdate? update in updates_) { if (update != null) { @@ -3083,17 +3080,19 @@ private void RunUpdates() } else { - baseStream_.Dispose(); + baseStream_?.Dispose(); Reopen(archiveStorage_.ConvertTemporaryToFinal()); } } + private class NotUpdatingException : InvalidOperationException + { + public NotUpdatingException() : base("BeginUpdate has not been called") { } + } + private void CheckUpdating() { - if (updates_ == null) - { - throw new InvalidOperationException("BeginUpdate has not been called"); - } + if (updates_ is null) throw new NotUpdatingException(); } #endregion Update Support @@ -3107,7 +3106,7 @@ private class ZipUpdate { #region Constructors - public ZipUpdate(string fileName, ZipEntry entry) + public ZipUpdate(string? fileName, ZipEntry entry) { command_ = UpdateCommand.Add; entry_ = entry; @@ -3115,7 +3114,7 @@ public ZipUpdate(string fileName, ZipEntry entry) } [Obsolete] - public ZipUpdate(string fileName, string entryName, CompressionMethod compressionMethod) + public ZipUpdate(string? fileName, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; entry_ = new ZipEntry(entryName) @@ -3126,14 +3125,14 @@ public ZipUpdate(string fileName, string entryName, CompressionMethod compressio } [Obsolete] - public ZipUpdate(string fileName, string entryName) + public ZipUpdate(string? fileName, string entryName) : this(fileName, entryName, CompressionMethod.Deflated) { // Do nothing. } [Obsolete] - public ZipUpdate(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod) + public ZipUpdate(IStaticDataSource? dataSource, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; entry_ = new ZipEntry(entryName) @@ -3143,14 +3142,14 @@ public ZipUpdate(IStaticDataSource dataSource, string entryName, CompressionMeth dataSource_ = dataSource; } - public ZipUpdate(IStaticDataSource dataSource, ZipEntry entry) + public ZipUpdate(IStaticDataSource? dataSource, ZipEntry entry) { command_ = UpdateCommand.Add; entry_ = entry; dataSource_ = dataSource; } - public ZipUpdate(ZipEntry original, ZipEntry updated) + public ZipUpdate(ZipEntry? original, ZipEntry? updated) { throw new ZipException("Modify not currently supported"); /* @@ -3214,7 +3213,7 @@ public UpdateCommand Command /// /// Get the filename if any for this update. Null if none exists. /// - public string Filename + public string? Filename { get { return filename_; } } @@ -3247,9 +3246,9 @@ public long OffsetBasedSize set { _offsetBasedSize = value; } } - public Stream GetSource() + public Stream? GetSource() { - Stream result = null; + Stream? result = null; if (dataSource_ != null) { result = dataSource_.GetSource(); @@ -3261,10 +3260,10 @@ public Stream GetSource() #region Instance Fields private ZipEntry entry_; - private ZipEntry outEntry_; + private ZipEntry? outEntry_; private readonly UpdateCommand command_; - private IStaticDataSource dataSource_; - private readonly string filename_; + private IStaticDataSource? dataSource_; + private readonly string? filename_; private long sizePatchOffset_ = -1; private long crcPatchOffset_ = -1; private long _offsetBasedSize = -1; @@ -3280,30 +3279,31 @@ public Stream GetSource() #region IDisposable Members - void IDisposable.Dispose() + /// + public void Dispose() { - Close(); + Dispose(true); + GC.SuppressFinalize(this); } #endregion IDisposable Members private void DisposeInternal(bool disposing) { - if (!isDisposed_) - { - isDisposed_ = true; - entries_ = new ZipEntry[0]; + if (isDisposed_) return; - if (IsStreamOwner && (baseStream_ != null)) + isDisposed_ = true; + entries_ = EmptyRefs.ZipEntryArray; + + if (IsStreamOwner && (baseStream_ != null)) + { + lock (baseStream_) { - lock (baseStream_) - { - baseStream_.Dispose(); - } + baseStream_.Dispose(); } - - PostUpdateCleanup(); } + + PostUpdateCleanup(); } /// @@ -3607,7 +3607,7 @@ private long LocateEntry(ZipEntry entry) private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) { - CryptoStream result = null; + CryptoStream? result = null; if (entry.CompressionMethodForHeader == CompressionMethod.WinZipAES) { @@ -3668,32 +3668,34 @@ private Stream CreateAndInitDecryptionStream(Stream baseStream, ZipEntry entry) private Stream CreateAndInitEncryptionStream(Stream baseStream, ZipEntry entry) { - CryptoStream result = null; - if ((entry.Version < ZipConstants.VersionStrongEncryption) - || (entry.Flags & (int)GeneralBitFlags.StrongEncryption) == 0) + if ((entry.Version >= ZipConstants.VersionStrongEncryption) && + (entry.Flags & (int) GeneralBitFlags.StrongEncryption) != 0) { - var classicManaged = new PkzipClassicManaged(); + throw new NotSupportedException("Entry version and/or encryption type not supported"); + } - OnKeysRequired(entry.Name); - if (HaveKeys == false) - { - throw new ZipException("No password available for encrypted stream"); - } + var classicManaged = new PkzipClassicManaged(); - // Closing a CryptoStream will close the base stream as well so wrap it in an UncompressedStream - // which doesnt do this. - result = new CryptoStream(new UncompressedStream(baseStream), - classicManaged.CreateEncryptor(key, null), CryptoStreamMode.Write); + OnKeysRequired(entry.Name); + if (HaveKeys == false) + { + throw new ZipException("No password available for encrypted stream"); + } - if ((entry.Crc < 0) || (entry.Flags & 8) != 0) - { - WriteEncryptionHeader(result, entry.DosTime << 16); - } - else - { - WriteEncryptionHeader(result, entry.Crc); - } + // Closing a CryptoStream will close the base stream as well so wrap it in an UncompressedStream + // which doesnt do this. + var result = new CryptoStream(new UncompressedStream(baseStream), + classicManaged.CreateEncryptor(key, null), CryptoStreamMode.Write); + + if ((entry.Crc < 0) || (entry.Flags & 8) != 0) + { + WriteEncryptionHeader(result, entry.DosTime << 16); } + else + { + WriteEncryptionHeader(result, entry.Crc); + } + return result; } @@ -3721,14 +3723,14 @@ private static void WriteEncryptionHeader(Stream stream, long crcValue) #region Instance Fields private bool isDisposed_; - private string name_; - private string comment_; - private string rawPassword_; + private string? name_; + private string? comment_; + private string? rawPassword_; private Stream baseStream_; private bool isStreamOwner; private long offsetOfFirstEntry; - private ZipEntry[] entries_; - private byte[] key; + private ZipEntry[] entries_ = EmptyRefs.ZipEntryArray; + private byte[]? key; private bool isNewArchive_; // Default is dynamic which is not backwards compatible and can cause problems @@ -3739,15 +3741,15 @@ private static void WriteEncryptionHeader(Stream stream, long crcValue) #region Zip Update Instance Fields - private List updates_; + private List? updates_; private long updateCount_; // Count is managed manually as updates_ can contain nulls! - private Dictionary updateIndex_; - private IArchiveStorage archiveStorage_; - private IDynamicDataSource updateDataSource_; + private Dictionary? updateIndex_; + private IArchiveStorage? archiveStorage_; + private IDynamicDataSource? updateDataSource_; private bool contentsEdited_; private int bufferSize_ = DefaultBufferSize; - private byte[] copyBuffer_; - private ZipString newComment_; + private byte[]? copyBuffer_; + private ZipString? newComment_; private bool commentEdited_; private IEntryFactory updateEntryFactory_ = new ZipEntryFactory(); @@ -3768,19 +3770,20 @@ private class ZipString /// Initialise a with a string. /// /// The textual string form. - public ZipString(string comment) + public ZipString(string? comment) { comment_ = comment; - isSourceString_ = true; + IsSourceString = true; } /// /// Initialise a using a string in its binary 'raw' form. /// /// - public ZipString(byte[] rawString) + public ZipString(byte[]? rawString) { rawComment_ = rawString; + IsSourceString = false; } #endregion Constructors @@ -3789,41 +3792,24 @@ public ZipString(byte[] rawString) /// Get a value indicating the original source of data for this instance. /// True if the source was a string; false if the source was binary data. /// - public bool IsSourceString - { - get { return isSourceString_; } - } + public bool IsSourceString { get; } /// /// Get the length of the comment when represented as raw bytes. /// - public int RawLength - { - get - { - MakeBytesAvailable(); - return rawComment_.Length; - } - } + public int RawLength => MakeBytesAvailable().Length; /// /// Get the comment in its 'raw' form as plain bytes. /// - public byte[] RawComment - { - get - { - MakeBytesAvailable(); - return (byte[])rawComment_.Clone(); - } - } + public byte[] RawComment => (byte[])MakeBytesAvailable().Clone(); /// /// Reset the comment to its initial state. /// public void Reset() { - if (isSourceString_) + if (IsSourceString) { rawComment_ = null; } @@ -3833,38 +3819,21 @@ public void Reset() } } - private void MakeTextAvailable() - { - if (comment_ == null) - { - comment_ = ZipStrings.ConvertToString(rawComment_); - } - } + private string MakeTextAvailable() => comment_ ??= ZipStrings.ConvertToString(rawComment_); - private void MakeBytesAvailable() - { - if (rawComment_ == null) - { - rawComment_ = ZipStrings.ConvertToArray(comment_); - } - } + private byte[] MakeBytesAvailable() => rawComment_ ??= ZipStrings.ConvertToArray(comment_); /// /// Implicit conversion of comment to a string. /// /// The to convert to a string. /// The textual equivalent for the input value. - static public implicit operator string(ZipString zipString) - { - zipString.MakeTextAvailable(); - return zipString.comment_; - } + public static implicit operator string?(ZipString zipString) => zipString.MakeTextAvailable(); #region Instance Fields - private string comment_; - private byte[] rawComment_; - private readonly bool isSourceString_; + private string? comment_; + private byte[]? rawComment_; #endregion Instance Fields } @@ -3876,7 +3845,7 @@ private class ZipEntryEnumerator : IEnumerator { #region Constructors - public ZipEntryEnumerator(ZipEntry[] entries) + public ZipEntryEnumerator(ZipEntry?[] entries) { array = entries; } @@ -3885,7 +3854,7 @@ public ZipEntryEnumerator(ZipEntry[] entries) #region IEnumerator Members - public object Current + public object? Current { get { @@ -3907,7 +3876,7 @@ public bool MoveNext() #region Instance Fields - private ZipEntry[] array; + private ZipEntry?[] array; private int index = -1; #endregion Instance Fields @@ -4010,7 +3979,7 @@ public override long Position /// buffer is null. /// An I/O error occurs. /// offset or count is negative. - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { return 0; } @@ -4054,7 +4023,7 @@ public override void SetLength(long value) /// buffer is null. /// The sum of offset and count is greater than the buffer length. /// offset or count is negative. - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { baseStream_.Write(buffer, offset, count); } @@ -4139,7 +4108,7 @@ public override int ReadByte() /// buffer is null. /// An I/O error occurs. /// offset or count is negative. - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { lock (baseStream_) { @@ -4178,7 +4147,7 @@ public override int Read(byte[] buffer, int offset, int count) /// buffer is null. /// The sum of offset and count is greater than the buffer length. /// offset or count is negative. - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { throw new NotSupportedException(); } @@ -4372,7 +4341,7 @@ public interface IDynamicDataSource /// The name for data if known. /// Returns a to use for compression input. /// Ideally a new stream is created and opened to achieve this, to avoid locking problems. - Stream GetSource(ZipEntry entry, string name); + Stream? GetSource(ZipEntry? entry, string? name); } /// @@ -4384,7 +4353,7 @@ public class StaticDiskDataSource : IStaticDataSource /// Initialise a new instance of /// /// The name of the file to obtain data from. - public StaticDiskDataSource(string fileName) + public StaticDiskDataSource(string? fileName) { fileName_ = fileName; } @@ -4406,7 +4375,7 @@ private readonly #region Instance Fields - string fileName_; + string? fileName_; #endregion Instance Fields } @@ -4424,9 +4393,9 @@ public class DynamicDiskDataSource : IDynamicDataSource /// The entry to provide data for. /// The file name for data if known. /// Returns a stream providing data; or null if not available - public Stream GetSource(ZipEntry entry, string name) + public Stream? GetSource(ZipEntry? entry, string? name) { - Stream result = null; + Stream? result = null; if (name != null) { @@ -4480,7 +4449,7 @@ public interface IArchiveStorage /// The current stream. /// Returns a stream suitable for direct updating. /// This may be the current stream passed. - Stream OpenForDirectUpdate(Stream stream); + Stream OpenForDirectUpdate(Stream? stream); /// /// Dispose of this instance. @@ -4535,7 +4504,7 @@ protected BaseArchiveStorage(FileUpdateMode updateMode) /// /// The to open for direct update. /// Returns a stream suitable for direct updating. - public abstract Stream OpenForDirectUpdate(Stream stream); + public abstract Stream OpenForDirectUpdate(Stream? stream); /// /// Disposes this instance. @@ -4633,7 +4602,7 @@ public override Stream ConvertTemporaryToFinal() throw new ZipException("No temporary stream has been created"); } - Stream result = null; + Stream? result = null; string moveTempName = GetTempFileName(fileName_, false); bool newFileCreated = false; @@ -4689,7 +4658,7 @@ public override Stream MakeTemporaryCopy(Stream stream) /// The current stream. /// Returns a stream suitable for direct updating. /// If the is not null this is used as is. - public override Stream OpenForDirectUpdate(Stream stream) + public override Stream OpenForDirectUpdate(Stream? stream) { Stream result; if ((stream == null) || !stream.CanWrite) @@ -4726,9 +4695,9 @@ public override void Dispose() #region Internal routines - private static string GetTempFileName(string original, bool makeTempFile) + private static string GetTempFileName(string? original, bool makeTempFile) { - string result = null; + string? result = null; if (original == null) { @@ -4774,9 +4743,9 @@ private static string GetTempFileName(string original, bool makeTempFile) #region Instance Fields - private Stream temporaryStream_; + private Stream? temporaryStream_; private readonly string fileName_; - private string temporaryName_; + private string? temporaryName_; #endregion Instance Fields } @@ -4813,7 +4782,7 @@ public MemoryArchiveStorage(FileUpdateMode updateMode) /// /// Get the stream returned by if this was in fact called. /// - public MemoryStream FinalStream + public MemoryStream? FinalStream { get { return finalStream_; } } @@ -4868,7 +4837,7 @@ public override Stream MakeTemporaryCopy(Stream stream) /// Returns a stream suitable for direct updating. /// If the passed is not null this is used; /// otherwise a new is returned. - public override Stream OpenForDirectUpdate(Stream stream) + public override Stream OpenForDirectUpdate(Stream? stream) { Stream result; if ((stream == null) || !stream.CanWrite) @@ -4906,8 +4875,8 @@ public override void Dispose() #region Instance Fields - private MemoryStream temporaryStream_; - private MemoryStream finalStream_; + private MemoryStream? temporaryStream_; + private MemoryStream? finalStream_; #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs index dd7d25d94..59bb7b77f 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipHelperStream.cs @@ -77,10 +77,10 @@ internal class ZipHelperStream : Stream /// Initialise an instance of this class. /// /// The name of the file to open. - public ZipHelperStream(string name) + public ZipHelperStream(string? name) { stream_ = new FileStream(name, FileMode.Open, FileAccess.ReadWrite); - isOwner_ = true; + IsStreamOwner = true; } /// @@ -98,44 +98,25 @@ public ZipHelperStream(Stream stream) /// Get / set a value indicating whether the underlying stream is owned or not. /// /// If the stream is owned it is closed when this instance is closed. - public bool IsStreamOwner - { - get { return isOwner_; } - set { isOwner_ = value; } - } + public bool IsStreamOwner { get; set; } #region Base Stream Methods - public override bool CanRead - { - get { return stream_.CanRead; } - } + public override bool CanRead => stream_.CanRead; - public override bool CanSeek - { - get { return stream_.CanSeek; } - } + public override bool CanSeek => stream_.CanSeek; - public override bool CanTimeout - { - get { return stream_.CanTimeout; } - } + public override bool CanTimeout => stream_.CanTimeout; - public override long Length - { - get { return stream_.Length; } - } + public override long Length => stream_.Length; public override long Position { - get { return stream_.Position; } - set { stream_.Position = value; } + get => stream_.Position; + set => stream_.Position = value; } - public override bool CanWrite - { - get { return stream_.CanWrite; } - } + public override bool CanWrite => stream_.CanWrite; public override void Flush() { @@ -152,12 +133,12 @@ public override void SetLength(long value) stream_.SetLength(value); } - public override int Read(byte[] buffer, int offset, int count) + public override int Read(byte[]? buffer, int offset, int count) { return stream_.Read(buffer, offset, count); } - public override void Write(byte[] buffer, int offset, int count) + public override void Write(byte[]? buffer, int offset, int count) { stream_.Write(buffer, offset, count); } @@ -170,13 +151,9 @@ public override void Write(byte[] buffer, int offset, int count) /// protected override void Dispose(bool disposing) { - Stream toClose = stream_; - stream_ = null; - if (isOwner_ && (toClose != null)) - { - isOwner_ = false; - toClose.Dispose(); - } + if (!IsStreamOwner || stream_ == null) return; + IsStreamOwner = false; + stream_.Dispose(); } #endregion Base Stream Methods @@ -285,7 +262,7 @@ private void WriteLocalHeader(ZipEntry entry, EntryPatchData patchData) stream_.Write(name, 0, name.Length); } - if (entry.LocalHeaderRequiresZip64 && patchEntryHeader) + if (entry.LocalHeaderRequiresZip64 && patchEntryHeader && patchData is {}) { patchData.SizePatchOffset += stream_.Position; } @@ -369,7 +346,7 @@ public void WriteZip64EndOfCentralDirectory(long noOfEntries, long sizeEntries, /// The start of the central directory. /// The archive comment. (This can be null). public void WriteEndOfCentralDirectory(long noOfEntries, long sizeEntries, - long startOfCentralDirectory, byte[] comment) + long startOfCentralDirectory, byte[]? comment) { if ((noOfEntries >= 0xffff) || (startOfCentralDirectory >= 0xffffffff) || @@ -416,18 +393,18 @@ public void WriteEndOfCentralDirectory(long noOfEntries, long sizeEntries, WriteLEInt((int)startOfCentralDirectory); } - int commentLength = (comment != null) ? comment.Length : 0; + int commentLength = comment?.Length ?? 0; if (commentLength > 0xffff) { - throw new ZipException(string.Format("Comment length({0}) is too long can only be 64K", commentLength)); + throw new ZipException($"Comment length {commentLength} is too long can only be 64K"); } WriteLEShort(commentLength); if (commentLength > 0) { - Write(comment, 0, comment.Length); + Write(comment, 0, commentLength); } } @@ -621,7 +598,6 @@ public void ReadDataDescriptor(bool zip64, DescriptorData data) #region Instance Fields - private bool isOwner_; private Stream stream_; #endregion Instance Fields diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs index 147d4043d..aa58adc1c 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipInputStream.cs @@ -70,12 +70,12 @@ public class ZipInputStream : InflaterInputStream private ReadDataHandler internalReader; private Crc32 crc = new Crc32(); - private ZipEntry entry; + private ZipEntry? entry; private long size; private CompressionMethod method; private int flags; - private string password; + private string? password; #endregion Instance Fields @@ -108,7 +108,7 @@ public ZipInputStream(Stream baseInputStream, int bufferSize) /// Optional password used for encryption when non-null /// /// A password for all encrypted entries in this - public string Password + public string? Password { get { @@ -151,7 +151,7 @@ public bool CanDecompressEntry /// Password is not set, password is invalid, compression method is invalid, /// version required to extract is not supported /// - public ZipEntry GetNextEntry() + public ZipEntry? GetNextEntry() { if (crc == null) { @@ -288,11 +288,13 @@ public ZipEntry GetNextEntry() /// private void ReadDataDescriptor() { + if(entry is null) throw new InvalidOperationException("No current entry"); + if (inputBuffer.ReadLeInt() != ZipConstants.DataDescriptorSignature) { throw new ZipException("Data descriptor signature not found"); } - + entry.Crc = inputBuffer.ReadLeInt() & 0xFFFFFFFFL; if (entry.LocalHeaderRequiresZip64) @@ -315,6 +317,8 @@ private void ReadDataDescriptor() /// True if the crc value should be tested private void CompleteCloseEntry(bool testCrc) { + if (entry is null) throw new InvalidOperationException("No current entry"); + StopDecrypting(); if ((flags & 8) != 0) @@ -487,11 +491,9 @@ 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 + ")"); - } - + if (entry is null) throw new InvalidOperationException("No current entry"); + if (!CanDecompressEntry) throw new ZipException($"Library cannot extract this entry. Version required is ({entry.Version})"); + // Handle encryption if required. if (entry.IsCrypted) { @@ -684,7 +686,6 @@ private int BodyRead(byte[] buffer, int offset, int count) protected override void Dispose(bool disposing) { internalReader = new ReadDataHandler(ReadingNotAvailable); - crc = null; entry = null; base.Dispose(disposing); diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs index 1b5e01a68..0f830f472 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipNameTransform.cs @@ -25,7 +25,7 @@ public ZipNameTransform() /// Initialize a new instance of /// /// The string to trim from the front of paths if found. - public ZipNameTransform(string trimPrefix) + public ZipNameTransform(string? trimPrefix) { TrimPrefix = trimPrefix; } @@ -60,7 +60,7 @@ static ZipNameTransform() /// /// The directory name to transform. /// The transformed name. - public string TransformDirectory(string name) + public string TransformDirectory(string? name) { name = TransformFile(name); if (name.Length > 0) @@ -82,7 +82,7 @@ public string TransformDirectory(string name) /// /// The file name to transform. /// The transformed name. - public string TransformFile(string name) + public string TransformFile(string? name) { if (name != null) { @@ -129,7 +129,7 @@ public string TransformFile(string name) /// /// The prefix is trimmed before any conversion from /// a windows path is done. - public string TrimPrefix + public string? TrimPrefix { get { return trimPrefix_; } set @@ -191,26 +191,12 @@ private static string MakeValidName(string name, char replacement) /// An empty name is valid for a file where the input comes from standard input. /// A null name is not considered valid. /// - public static bool IsValidName(string name, bool relaxed) - { - bool result = (name != null); - - if (result) - { - if (relaxed) - { - result = name.IndexOfAny(InvalidEntryCharsRelaxed) < 0; - } - else - { - result = - (name.IndexOfAny(InvalidEntryChars) < 0) && - (name.IndexOf('/') != 0); - } - } - - return result; - } + public static bool IsValidName(string? name, bool relaxed) + => name is {} + && (relaxed + ? name.IndexOfAny(InvalidEntryCharsRelaxed) < 0 + : name.IndexOfAny(InvalidEntryChars) < 0 && + name.IndexOf('/') != 0); /// /// Test a name to see if it is a valid name for a zip entry. @@ -224,19 +210,11 @@ public static bool IsValidName(string name, bool relaxed) /// An empty name is valid where the input comes from standard input. /// A null name is not considered valid. /// - public static bool IsValidName(string name) - { - bool result = - (name != null) && - (name.IndexOfAny(InvalidEntryChars) < 0) && - (name.IndexOf('/') != 0) - ; - return result; - } + public static bool IsValidName(string? name) => IsValidName(name, false); #region Instance Fields - private string trimPrefix_; + private string? trimPrefix_; #endregion Instance Fields diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs index bfd308daa..2b45bc9aa 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs @@ -98,7 +98,7 @@ public bool IsFinished /// /// The converted comment is longer than 0xffff bytes. /// - public void SetComment(string comment) + public void SetComment(string? comment) { // TODO: Its not yet clear how to handle unicode comments here. byte[] commentBytes = ZipStrings.ConvertToArray(comment); @@ -712,7 +712,7 @@ public override void Write(byte[] buffer, int offset, int count) } } - private void CopyAndEncrypt(byte[] buffer, int offset, int count) + private void CopyAndEncrypt(byte[]? buffer, int offset, int count) { const int CopyBufferSize = 4096; byte[] localBuffer = new byte[CopyBufferSize]; @@ -894,7 +894,7 @@ public override void Finish() zhs.WriteEndOfCentralDirectory(numEntries, sizeEntries, offset, zipComment); } - entries = null; + entries.Clear(); } /// @@ -928,7 +928,7 @@ public override void Flush() /// /// The current entry being added. /// - private ZipEntry curEntry; + private ZipEntry? curEntry; private int defaultCompressionLevel = Deflater.DEFAULT_COMPRESSION; diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs index 6ef523b82..340257c55 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipStrings.cs @@ -107,7 +107,7 @@ public static bool UseUnicode /// /// data[0]..data[count - 1] converted to a string /// - public static string ConvertToString(byte[] data, int count) + public static string ConvertToString(byte[]? data, int count) => data == null ? string.Empty : Encoding.GetEncoding(CodePage).GetString(data, 0, count); @@ -121,8 +121,8 @@ public static string ConvertToString(byte[] data, int count) /// /// dataconverted to a string /// - public static string ConvertToString(byte[] data) - => ConvertToString(data, data.Length); + public static string ConvertToString(byte[]? data) + => ConvertToString(data, data?.Length ?? 0); private static Encoding EncodingFromFlag(int flags) => ((flags & (int)GeneralBitFlags.UnicodeText) != 0) @@ -147,7 +147,7 @@ private static Encoding EncodingFromFlag(int flags) /// /// dataconverted to a string /// - public static string ConvertToStringExt(int flags, byte[] data, int count) + public static string ConvertToStringExt(int flags, byte[]? data, int count) => (data == null) ? string.Empty : EncodingFromFlag(flags).GetString(data, 0, count); @@ -172,7 +172,7 @@ public static string ConvertToStringExt(int flags, byte[] data) /// String to convert to an array /// /// Converted array - public static byte[] ConvertToArray(string str) + public static byte[] ConvertToArray(string? str) => str == null ? new byte[0] : Encoding.GetEncoding(CodePage).GetBytes(str); @@ -185,7 +185,7 @@ public static byte[] ConvertToArray(string str) /// String to convert to an array /// /// Converted array - public static byte[] ConvertToArray(int flags, string str) + public static byte[] ConvertToArray(int flags, string? str) => (string.IsNullOrEmpty(str)) ? new byte[0] : EncodingFromFlag(flags).GetBytes(str); From 4fd140bd132e0c185eb66d1c8ed8d231581a44de Mon Sep 17 00:00:00 2001 From: p1ksel Date: Thu, 6 Aug 2020 02:09:33 +0200 Subject: [PATCH 3/5] Upgrade AppVeyor builds to VS 2019 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index a6197ff29..4da8101a0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,5 @@ version: '{build}' -image: Visual Studio 2017 +image: Visual Studio 2019 configuration: - Debug - Release From fedb0def3de847af859184f249c5fd46d6d79c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Fri, 7 Aug 2020 14:51:51 +0200 Subject: [PATCH 4/5] Remove nullable markers and simplify Array.Empty --- ICSharpCode.SharpZipLib.sln.DotSettings | 5 +++++ .../BZip2/BZip2Exception.cs | 6 +++--- .../BZip2/BZip2InputStream.cs | 4 ++-- .../BZip2/BZip2OutputStream.cs | 12 ++++++------ src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs | 16 +++++++--------- .../Core/Exceptions/SharpZipBaseException.cs | 6 +++--- .../Core/Exceptions/StreamDecodingException.cs | 8 ++++---- .../Exceptions/StreamUnsupportedException.cs | 6 +++--- .../Exceptions/UnexpectedEndOfStreamException.cs | 6 +++--- .../Core/Exceptions/ValueOutOfRangeException.cs | 10 +++++----- .../Core/InvalidNameException.cs | 6 +++--- src/ICSharpCode.SharpZipLib/GZip/GZip.cs | 4 ++-- .../GZip/GZipException.cs | 6 +++--- src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs | 6 +++--- .../Tar/InvalidHeaderException.cs | 8 ++++---- src/ICSharpCode.SharpZipLib/Tar/TarException.cs | 6 +++--- .../Zip/Compression/DeflaterHuffman.cs | 8 ++++---- .../Zip/Compression/Streams/StreamManipulator.cs | 2 +- src/ICSharpCode.SharpZipLib/Zip/ZipException.cs | 6 +++--- src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs | 6 +++--- src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs | 6 +++--- .../Zip/FastZipHandling.cs | 2 +- 22 files changed, 74 insertions(+), 71 deletions(-) create mode 100644 ICSharpCode.SharpZipLib.sln.DotSettings diff --git a/ICSharpCode.SharpZipLib.sln.DotSettings b/ICSharpCode.SharpZipLib.sln.DotSettings new file mode 100644 index 000000000..bae19b769 --- /dev/null +++ b/ICSharpCode.SharpZipLib.sln.DotSettings @@ -0,0 +1,5 @@ + + IV + True + True + True \ No newline at end of file diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs index 451ccc004..111d21cdc 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2Exception.cs @@ -20,7 +20,7 @@ public BZip2Exception() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public BZip2Exception(string? message) + public BZip2Exception(string message) : base(message) { } @@ -30,7 +30,7 @@ public BZip2Exception(string? message) /// /// A that describes the error. /// The that caused this exception. - public BZip2Exception(string? message, Exception? innerException) + public BZip2Exception(string message, Exception innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public BZip2Exception(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected BZip2Exception(SerializationInfo? info, StreamingContext context) + protected BZip2Exception(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs index f4b704323..2ed9ecefd 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2InputStream.cs @@ -56,8 +56,8 @@ The current block size is 100000 * this number. private byte[] selector = new byte[BZip2Constants.MaximumSelectors]; private byte[] selectorMtf = new byte[BZip2Constants.MaximumSelectors]; - private int[] tt = EmptyRefs.Int32Array; - private byte[] ll8 = EmptyRefs.ByteArray; + private int[] tt = Empty.Array(); + private byte[] ll8 = Empty.Array(); /*-- freq table collected to save a pass over the data diff --git a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs index 1d1398b9d..953cbd328 100644 --- a/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/BZip2/BZip2OutputStream.cs @@ -80,11 +80,11 @@ The current block size is 100000 * this number. private char[] selector = new char[BZip2Constants.MaximumSelectors]; private char[] selectorMtf = new char[BZip2Constants.MaximumSelectors]; - private byte[] block = EmptyRefs.ByteArray; - private int[] quadrant = EmptyRefs.Int32Array; - private int[] zptr = EmptyRefs.Int32Array; - private short[] szptr = EmptyRefs.Int16Array; - private int[] ftab = EmptyRefs.Int32Array; + private byte[] block = Empty.Array(); + private int[] quadrant = Empty.Array(); + private int[] zptr = Empty.Array(); + private short[] szptr = Empty.Array(); + private int[] ftab = Empty.Array(); private int nMTF; @@ -1692,7 +1692,7 @@ private void AllocateCompressStructures() zptr = new int[n]; ftab = new int[65537]; - if (block == EmptyRefs.ByteArray || quadrant == null || zptr == null || ftab == null) + if (block == Empty.Array() || quadrant == null || zptr == null || ftab == null) { // int totalDraw = (n + 1 + NUM_OVERSHOOT_BYTES) + (n + NUM_OVERSHOOT_BYTES) + n + 65537; // compressOutOfMemory ( totalDraw, n ); diff --git a/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs b/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs index 4c183ff44..16e23650b 100644 --- a/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs +++ b/src/ICSharpCode.SharpZipLib/Core/EmptyRefs.cs @@ -5,18 +5,16 @@ namespace ICSharpCode.SharpZipLib.Core { - internal static class EmptyRefs + internal static class Empty { #if NET45 - public static byte[] ByteArray { get; } = new byte[0]; - public static int[] Int32Array { get; } = new int[0]; - public static short[] Int16Array {get; } = new short[0]; - public static ZipEntry[] ZipEntryArray { get; } = new ZipEntry[0]; + internal static class EmptyArray + { + public static readonly T[] Value = new T[0]; + } + public static T[] Array() => EmptyArray.Value; #else - public static byte[] ByteArray => Array.Empty(); - public static int[] Int32Array => Array.Empty(); - public static short[] Int16Array => Array.Empty(); - public static ZipEntry[] ZipEntryArray => Array.Empty(); + public static T[] Array() => System.Array.Empty(); #endif } } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs index 18daa218c..eb14e2d49 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/SharpZipBaseException.cs @@ -23,7 +23,7 @@ public SharpZipBaseException() /// Initializes a new instance of the SharpZipBaseException class with a specified error message. /// /// A message describing the exception. - public SharpZipBaseException(string? message) + public SharpZipBaseException(string message) : base(message) { } @@ -34,7 +34,7 @@ public SharpZipBaseException(string? message) /// /// A message describing the exception. /// The inner exception - public SharpZipBaseException(string? message, Exception? innerException) + public SharpZipBaseException(string message, Exception innerException) : base(message, innerException) { } @@ -50,7 +50,7 @@ public SharpZipBaseException(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected SharpZipBaseException(SerializationInfo? info, StreamingContext context) + protected SharpZipBaseException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs index 1c2eec699..ded5d37b8 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamDecodingException.cs @@ -5,7 +5,7 @@ namespace ICSharpCode.SharpZipLib { /// /// Indicates that an error occured during decoding of a input stream due to corrupt - /// data or (unintentional) library incompability. + /// data or (unintentional) library incompatibility. /// [Serializable] public class StreamDecodingException : SharpZipBaseException @@ -21,7 +21,7 @@ public StreamDecodingException() : base(GenericMessage) { } /// Initializes a new instance of the StreamDecodingException class with a specified error message. /// /// A message describing the exception. - public StreamDecodingException(string? message) : base(message) { } + public StreamDecodingException(string message) : base(message) { } /// /// Initializes a new instance of the StreamDecodingException class with a specified @@ -29,7 +29,7 @@ public StreamDecodingException(string? message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public StreamDecodingException(string? message, Exception? innerException) : base(message, innerException) { } + public StreamDecodingException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the StreamDecodingException class with serialized data. @@ -42,7 +42,7 @@ public StreamDecodingException(string? message, Exception? innerException) : bas /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected StreamDecodingException(SerializationInfo? info, StreamingContext context) + protected StreamDecodingException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs index 2e8d2a252..5827e559d 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/StreamUnsupportedException.cs @@ -20,7 +20,7 @@ public StreamUnsupportedException() : base(GenericMessage) { } /// Initializes a new instance of the StreamUnsupportedException class with a specified error message. /// /// A message describing the exception. - public StreamUnsupportedException(string? message) : base(message) { } + public StreamUnsupportedException(string message) : base(message) { } /// /// Initializes a new instance of the StreamUnsupportedException class with a specified @@ -28,7 +28,7 @@ public StreamUnsupportedException(string? message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public StreamUnsupportedException(string? message, Exception? innerException) : base(message, innerException) { } + public StreamUnsupportedException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the StreamUnsupportedException class with serialized data. @@ -41,7 +41,7 @@ public StreamUnsupportedException(string? message, Exception? innerException) : /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected StreamUnsupportedException(SerializationInfo? info, StreamingContext context) + protected StreamUnsupportedException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs index a17d859fc..a35c49f03 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/UnexpectedEndOfStreamException.cs @@ -20,7 +20,7 @@ public UnexpectedEndOfStreamException() : base(GenericMessage) { } /// Initializes a new instance of the UnexpectedEndOfStreamException class with a specified error message. /// /// A message describing the exception. - public UnexpectedEndOfStreamException(string? message) : base(message) { } + public UnexpectedEndOfStreamException(string message) : base(message) { } /// /// Initializes a new instance of the UnexpectedEndOfStreamException class with a specified @@ -28,7 +28,7 @@ public UnexpectedEndOfStreamException(string? message) : base(message) { } /// /// A message describing the exception. /// The inner exception - public UnexpectedEndOfStreamException(string? message, Exception? innerException) : base(message, innerException) { } + public UnexpectedEndOfStreamException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the UnexpectedEndOfStreamException class with serialized data. @@ -41,7 +41,7 @@ public UnexpectedEndOfStreamException(string? message, Exception? innerException /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected UnexpectedEndOfStreamException(SerializationInfo? info, StreamingContext context) + protected UnexpectedEndOfStreamException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs index f7a3c759e..d41cf9882 100644 --- a/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/Exceptions/ValueOutOfRangeException.cs @@ -13,7 +13,7 @@ public class ValueOutOfRangeException : StreamDecodingException /// Initializes a new instance of the ValueOutOfRangeException class naming the causing variable /// /// Name of the variable, use: nameof() - public ValueOutOfRangeException(string? nameOfValue) + public ValueOutOfRangeException(string nameOfValue) : base($"{nameOfValue} out of range") { } /// @@ -24,7 +24,7 @@ public ValueOutOfRangeException(string? nameOfValue) /// The invalid value /// Expected maximum value /// Expected minimum value - public ValueOutOfRangeException(string? nameOfValue, long value, long maxValue, long minValue = 0) + public ValueOutOfRangeException(string nameOfValue, long value, long maxValue, long minValue = 0) : this(nameOfValue, value.ToString(), maxValue.ToString(), minValue.ToString()) { } /// @@ -35,7 +35,7 @@ public ValueOutOfRangeException(string? nameOfValue, long value, long maxValue, /// The invalid value /// Expected maximum value /// Expected minimum value - public ValueOutOfRangeException(string? nameOfValue, string? value, string? maxValue, string? minValue = "0") : + public ValueOutOfRangeException(string nameOfValue, string value, string maxValue, string minValue = "0") : base($"{nameOfValue} out of range: {value}, should be {minValue}..{maxValue}") { } @@ -43,7 +43,7 @@ private ValueOutOfRangeException() { } - private ValueOutOfRangeException(string? message, Exception? innerException) : base(message, innerException) + private ValueOutOfRangeException(string message, Exception innerException) : base(message, innerException) { } @@ -58,7 +58,7 @@ private ValueOutOfRangeException(string? message, Exception? innerException) : b /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected ValueOutOfRangeException(SerializationInfo? info, StreamingContext context) + protected ValueOutOfRangeException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs index 0c353af86..6647631bd 100644 --- a/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs +++ b/src/ICSharpCode.SharpZipLib/Core/InvalidNameException.cs @@ -20,7 +20,7 @@ public InvalidNameException() : base("An invalid name was specified") /// Initializes a new instance of the InvalidNameException class with a specified error message. /// /// A message describing the exception. - public InvalidNameException(string? message) : base(message) + public InvalidNameException(string message) : base(message) { } @@ -30,7 +30,7 @@ public InvalidNameException(string? message) : base(message) /// /// A message describing the exception. /// The inner exception - public InvalidNameException(string? message, Exception? innerException) : base(message, innerException) + public InvalidNameException(string message, Exception innerException) : base(message, innerException) { } @@ -45,7 +45,7 @@ public InvalidNameException(string? message, Exception? innerException) : base(m /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected InvalidNameException(SerializationInfo? info, StreamingContext context) + protected InvalidNameException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs index 50c26c1bc..e7e4763da 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZip.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZip.cs @@ -18,7 +18,7 @@ public static class GZip /// The output stream to receive the decompressed data. /// Both streams are closed on completion if true. /// Input or output stream is null - public static void Decompress(Stream? inStream, Stream? outStream, bool isStreamOwner) + public static void Decompress(Stream inStream, Stream outStream, bool isStreamOwner) { if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); @@ -56,7 +56,7 @@ public static void Decompress(Stream? inStream, Stream? outStream, bool isStream /// Input or output stream is null /// Buffer Size is smaller than 512 /// Compression level outside 0-9 - public static void Compress(Stream? inStream, Stream? outStream, bool isStreamOwner, int bufferSize = 512, int level = 6) + public static void Compress(Stream inStream, Stream outStream, bool isStreamOwner, int bufferSize = 512, int level = 6) { if (inStream == null) throw new ArgumentNullException(nameof(inStream), "Input stream is null"); diff --git a/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs b/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs index dbf1acb2a..a0ec6bb51 100644 --- a/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs +++ b/src/ICSharpCode.SharpZipLib/GZip/GZipException.cs @@ -20,7 +20,7 @@ public GZipException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public GZipException(string? message) + public GZipException(string message) : base(message) { } @@ -30,7 +30,7 @@ public GZipException(string? message) /// /// A that describes the error. /// The that caused this exception. - public GZipException(string? message, Exception? innerException) + public GZipException(string message, Exception innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public GZipException(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected GZipException(SerializationInfo? info, StreamingContext context) + protected GZipException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs b/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs index c5b0d4fcb..1d5c44c3c 100644 --- a/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs +++ b/src/ICSharpCode.SharpZipLib/Lzw/LzwException.cs @@ -20,7 +20,7 @@ public LzwException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public LzwException(string? message) + public LzwException(string message) : base(message) { } @@ -30,7 +30,7 @@ public LzwException(string? message) /// /// A that describes the error. /// The that caused this exception. - public LzwException(string? message, Exception? innerException) + public LzwException(string message, Exception innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public LzwException(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected LzwException(SerializationInfo? info, StreamingContext context) + protected LzwException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs b/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs index 959b585ff..9d39086b7 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/InvalidHeaderException.cs @@ -18,10 +18,10 @@ public InvalidHeaderException() } /// - /// Initialises a new instance of the InvalidHeaderException class with a specified message. + /// Initializes a new instance of the InvalidHeaderException class with a specified message. /// /// Message describing the exception cause. - public InvalidHeaderException(string? message) + public InvalidHeaderException(string message) : base(message) { } @@ -31,7 +31,7 @@ public InvalidHeaderException(string? message) /// /// Message describing the problem. /// The exception that is the cause of the current exception. - public InvalidHeaderException(string? message, Exception? exception) + public InvalidHeaderException(string message, Exception exception) : base(message, exception) { } @@ -47,7 +47,7 @@ public InvalidHeaderException(string? message, Exception? exception) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected InvalidHeaderException(SerializationInfo? info, StreamingContext context) + protected InvalidHeaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs index 0de1133a3..9d448ca7d 100644 --- a/src/ICSharpCode.SharpZipLib/Tar/TarException.cs +++ b/src/ICSharpCode.SharpZipLib/Tar/TarException.cs @@ -20,7 +20,7 @@ public TarException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public TarException(string? message) + public TarException(string message) : base(message) { } @@ -30,7 +30,7 @@ public TarException(string? message) /// /// A that describes the error. /// The that caused this exception. - public TarException(string? message, Exception? innerException) + public TarException(string message, Exception innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public TarException(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected TarException(SerializationInfo? info, StreamingContext context) + protected TarException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs index bf5b5537b..c911a2b2e 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/DeflaterHuffman.cs @@ -67,13 +67,13 @@ private class Tree public short[] freqs; - public byte[] length = EmptyRefs.ByteArray; + public byte[] length = Empty.Array(); public int minNumCodes; public int numCodes; - private short[] codes = EmptyRefs.Int16Array; + private short[] codes = Empty.Array(); private readonly int[] bl_counts; private readonly int maxLength; private DeflaterHuffman dh; @@ -102,8 +102,8 @@ public void Reset() { freqs[i] = 0; } - codes = EmptyRefs.Int16Array; - length = EmptyRefs.ByteArray; + codes = Empty.Array(); + length = Empty.Array(); } public void WriteSymbol(int code) diff --git a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs index e7069b595..77e14c264 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/Compression/Streams/StreamManipulator.cs @@ -287,7 +287,7 @@ public void SetInput(byte[] buffer, int offset, int count) #region Instance Fields - private byte[] window_ = EmptyRefs.ByteArray; + private byte[] window_ = Empty.Array(); private int windowStart_; private int windowEnd_; diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs index e0b208f42..ef8142b65 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipException.cs @@ -20,7 +20,7 @@ public ZipException() /// Initialise a new instance of with its message string. /// /// A that describes the error. - public ZipException(string? message) + public ZipException(string message) : base(message) { } @@ -30,7 +30,7 @@ public ZipException(string? message) /// /// A that describes the error. /// The that caused this exception. - public ZipException(string? message, Exception? innerException) + public ZipException(string message, Exception innerException) : base(message, innerException) { } @@ -46,7 +46,7 @@ public ZipException(string? message, Exception? innerException) /// The System.Runtime.Serialization.StreamingContext that contains contextual information /// about the source or destination. /// - protected ZipException(SerializationInfo? info, StreamingContext context) + protected ZipException(SerializationInfo info, StreamingContext context) : base(info, context) { } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs index 65ae67266..977df3fb1 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipExtraData.cs @@ -545,7 +545,7 @@ public void Clear() { if (_data.Length != 0) { - _data = EmptyRefs.ByteArray; + _data = Empty.Array(); } } @@ -728,7 +728,7 @@ public void StartNewEntry() /// The identifier to use for this entry. public void AddNewEntry(int headerID) { - byte[] newData = _newEntry?.ToArray() ?? EmptyRefs.ByteArray; + byte[] newData = _newEntry?.ToArray() ?? Empty.Array(); _newEntry = null; AddEntry(headerID, newData); } @@ -954,7 +954,7 @@ public void Dispose() private int _readValueLength; private MemoryStream? _newEntry; - private byte[] _data = EmptyRefs.ByteArray; + private byte[] _data = Empty.Array(); #endregion Instance Fields } diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs index 6352da6ec..90f622596 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs @@ -2851,7 +2851,7 @@ private void UpdateCommentOnly() const int CentralHeaderCommentSizeOffset = 16; updateFile.Position += CentralHeaderCommentSizeOffset; - byte[] rawComment = newComment_?.RawComment ?? EmptyRefs.ByteArray; + byte[] rawComment = newComment_?.RawComment ?? Empty.Array(); updateFile.WriteLEShort(rawComment.Length); updateFile.Write(rawComment, 0, rawComment.Length); @@ -3293,7 +3293,7 @@ private void DisposeInternal(bool disposing) if (isDisposed_) return; isDisposed_ = true; - entries_ = EmptyRefs.ZipEntryArray; + entries_ = Empty.Array(); if (IsStreamOwner && (baseStream_ != null)) { @@ -3729,7 +3729,7 @@ private static void WriteEncryptionHeader(Stream stream, long crcValue) private Stream baseStream_; private bool isStreamOwner; private long offsetOfFirstEntry; - private ZipEntry[] entries_ = EmptyRefs.ZipEntryArray; + private ZipEntry[] entries_ = Empty.Array(); private byte[]? key; private bool isNewArchive_; diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs index 67b481f65..c2e553da5 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/FastZipHandling.cs @@ -611,7 +611,7 @@ public void SetDirectoryModifiedDate() File.Delete(zipName); - // Check that the empty sub folder exists and has the expected modlfied date + // Check that the empty sub folder exists and has the expected modified date string emptyTargetDir = Path.Combine(targetDir, "emptyFolder"); Assert.That(Directory.Exists(emptyTargetDir), Is.True, "Empty directory should be created"); From c62fbb0c912d1c1755a45e70479c8dc006aefe29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nils=20m=C3=A5s=C3=A9n?= Date: Fri, 7 Aug 2020 14:52:25 +0200 Subject: [PATCH 5/5] Fix finish indicator in ZipOutputStream --- src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs index 2b45bc9aa..8b8eb0c4f 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs @@ -81,13 +81,7 @@ public ZipOutputStream(Stream baseOutputStream, int bufferSize) /// Gets a flag value of true if the central header has been added for this archive; false if it has not been added. /// /// No further entries can be added once this has been done. - public bool IsFinished - { - get - { - return entries == null; - } - } + public bool IsFinished { get; private set; } = false; /// /// Set the zip file comment. @@ -216,7 +210,7 @@ public void PutNextEntry(ZipEntry entry) throw new ArgumentNullException(nameof(entry)); } - if (entries == null) + if (IsFinished) { throw new InvalidOperationException("ZipOutputStream was finished"); } @@ -744,7 +738,7 @@ private void CopyAndEncrypt(byte[]? buffer, int offset, int count) /// public override void Finish() { - if (entries == null) + if (IsFinished) { return; } @@ -895,6 +889,7 @@ public override void Finish() } entries.Clear(); + IsFinished = true; } ///