Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.EPPlus/4.0.3/EPPlus-4.0.3/Packaging/DotNetZip/ZipFile.Check.cs @ 18172

Last change on this file since 18172 was 12074, checked in by sraggl, 10 years ago

#2341: Added EPPlus-4.0.3 to ExtLibs

File size: 13.8 KB
Line 
1// ZipFile.Check.cs
2// ------------------------------------------------------------------
3//
4// Copyright (c) 2009-2011 Dino Chiesa.
5// All rights reserved.
6//
7// This code module is part of DotNetZip, a zipfile class library.
8//
9// ------------------------------------------------------------------
10//
11// This code is licensed under the Microsoft Public License.
12// See the file License.txt for the license details.
13// More info on: http://dotnetzip.codeplex.com
14//
15// ------------------------------------------------------------------
16//
17// last saved (in emacs):
18// Time-stamp: <2011-July-31 14:40:50>
19//
20// ------------------------------------------------------------------
21//
22// This module defines the methods for doing Checks on zip files.
23// These are not necessary to include in the Reduced or CF
24// version of the library.
25//
26// ------------------------------------------------------------------
27//
28
29
30using System;
31using System.IO;
32using System.Collections.Generic;
33
34namespace OfficeOpenXml.Packaging.Ionic.Zip
35{
36    internal partial class ZipFile
37    {
38        /// <summary>
39        ///   Checks a zip file to see if its directory is consistent.
40        /// </summary>
41        ///
42        /// <remarks>
43        ///
44        /// <para>
45        ///   In cases of data error, the directory within a zip file can get out
46        ///   of synch with the entries in the zip file.  This method checks the
47        ///   given zip file and returns true if this has occurred.
48        /// </para>
49        ///
50        /// <para> This method may take a long time to run for large zip files.  </para>
51        ///
52        /// <para>
53        ///   This method is not supported in the Reduced or Compact Framework
54        ///   versions of DotNetZip.
55        /// </para>
56        ///
57        /// <para>
58        ///   Developers using COM can use the <see
59        ///   cref="ComHelper.CheckZip(String)">ComHelper.CheckZip(String)</see>
60        ///   method.
61        /// </para>
62        ///
63        /// </remarks>
64        ///
65        /// <param name="zipFileName">The filename to of the zip file to check.</param>
66        ///
67        /// <returns>true if the named zip file checks OK. Otherwise, false. </returns>
68        ///
69        /// <seealso cref="FixZipDirectory(string)"/>
70        /// <seealso cref="CheckZip(string,bool,System.IO.TextWriter)"/>
71        public static bool CheckZip(string zipFileName)
72        {
73            return CheckZip(zipFileName, false, null);
74        }
75
76
77        /// <summary>
78        ///   Checks a zip file to see if its directory is consistent,
79        ///   and optionally fixes the directory if necessary.
80        /// </summary>
81        ///
82        /// <remarks>
83        ///
84        /// <para>
85        ///   In cases of data error, the directory within a zip file can get out of
86        ///   synch with the entries in the zip file.  This method checks the given
87        ///   zip file, and returns true if this has occurred. It also optionally
88        ///   fixes the zipfile, saving the fixed copy in <em>Name</em>_Fixed.zip.
89        /// </para>
90        ///
91        /// <para>
92        ///   This method may take a long time to run for large zip files.  It
93        ///   will take even longer if the file actually needs to be fixed, and if
94        ///   <c>fixIfNecessary</c> is true.
95        /// </para>
96        ///
97        /// <para>
98        ///   This method is not supported in the Reduced or Compact
99        ///   Framework versions of DotNetZip.
100        /// </para>
101        ///
102        /// </remarks>
103        ///
104        /// <param name="zipFileName">The filename to of the zip file to check.</param>
105        ///
106        /// <param name="fixIfNecessary">If true, the method will fix the zip file if
107        ///     necessary.</param>
108        ///
109        /// <param name="writer">
110        /// a TextWriter in which messages generated while checking will be written.
111        /// </param>
112        ///
113        /// <returns>true if the named zip is OK; false if the file needs to be fixed.</returns>
114        ///
115        /// <seealso cref="CheckZip(string)"/>
116        /// <seealso cref="FixZipDirectory(string)"/>
117        public static bool CheckZip(string zipFileName, bool fixIfNecessary,
118                                    TextWriter writer)
119
120        {
121            ZipFile zip1 = null, zip2 = null;
122            bool isOk = true;
123            try
124            {
125                zip1 = new ZipFile();
126                zip1.FullScan = true;
127                zip1.Initialize(zipFileName);
128
129                zip2 = ZipFile.Read(zipFileName);
130
131                foreach (var e1 in zip1)
132                {
133                    foreach (var e2 in zip2)
134                    {
135                        if (e1.FileName == e2.FileName)
136                        {
137                            if (e1._RelativeOffsetOfLocalHeader != e2._RelativeOffsetOfLocalHeader)
138                            {
139                                isOk = false;
140                                if (writer != null)
141                                writer.WriteLine("{0}: mismatch in RelativeOffsetOfLocalHeader  (0x{1:X16} != 0x{2:X16})",
142                                                        e1.FileName, e1._RelativeOffsetOfLocalHeader,
143                                                        e2._RelativeOffsetOfLocalHeader);
144                            }
145                            if (e1._CompressedSize != e2._CompressedSize)
146                            {
147                                isOk = false;
148                                if (writer != null)
149                                writer.WriteLine("{0}: mismatch in CompressedSize  (0x{1:X16} != 0x{2:X16})",
150                                                        e1.FileName, e1._CompressedSize,
151                                                        e2._CompressedSize);
152                            }
153                            if (e1._UncompressedSize != e2._UncompressedSize)
154                            {
155                                isOk = false;
156                                if (writer != null)
157                                writer.WriteLine("{0}: mismatch in UncompressedSize  (0x{1:X16} != 0x{2:X16})",
158                                                        e1.FileName, e1._UncompressedSize,
159                                                        e2._UncompressedSize);
160                            }
161                            if (e1.CompressionMethod != e2.CompressionMethod)
162                            {
163                                isOk = false;
164                                if (writer != null)
165                                writer.WriteLine("{0}: mismatch in CompressionMethod  (0x{1:X4} != 0x{2:X4})",
166                                                        e1.FileName, e1.CompressionMethod,
167                                                        e2.CompressionMethod);
168                            }
169                            if (e1.Crc != e2.Crc)
170                            {
171                                isOk = false;
172                                if (writer != null)
173                                writer.WriteLine("{0}: mismatch in Crc32  (0x{1:X4} != 0x{2:X4})",
174                                                        e1.FileName, e1.Crc,
175                                                        e2.Crc);
176                            }
177
178                            // found a match, so stop the inside loop
179                            break;
180                        }
181                    }
182                }
183
184                zip2.Dispose();
185                zip2 = null;
186
187                if (!isOk && fixIfNecessary)
188                {
189                    string newFileName = Path.GetFileNameWithoutExtension(zipFileName);
190                    newFileName = System.String.Format("{0}_fixed.zip", newFileName);
191                    zip1.Save(newFileName);
192                }
193            }
194            finally
195            {
196                if (zip1 != null) zip1.Dispose();
197                if (zip2 != null) zip2.Dispose();
198            }
199            return isOk;
200        }
201
202
203
204        /// <summary>
205        ///   Rewrite the directory within a zipfile.
206        /// </summary>
207        ///
208        /// <remarks>
209        ///
210        /// <para>
211        ///   In cases of data error, the directory in a zip file can get out of
212        ///   synch with the entries in the zip file.  This method attempts to fix
213        ///   the zip file if this has occurred.
214        /// </para>
215        ///
216        /// <para> This can take a long time for large zip files. </para>
217        ///
218        /// <para> This won't work if the zip file uses a non-standard
219        /// code page - neither IBM437 nor UTF-8. </para>
220        ///
221        /// <para>
222        ///   This method is not supported in the Reduced or Compact Framework
223        ///   versions of DotNetZip.
224        /// </para>
225        ///
226        /// <para>
227        ///   Developers using COM can use the <see
228        ///   cref="ComHelper.FixZipDirectory(String)">ComHelper.FixZipDirectory(String)</see>
229        ///   method.
230        /// </para>
231        ///
232        /// </remarks>
233        ///
234        /// <param name="zipFileName">The filename to of the zip file to fix.</param>
235        ///
236        /// <seealso cref="CheckZip(string)"/>
237        /// <seealso cref="CheckZip(string,bool,System.IO.TextWriter)"/>
238        public static void FixZipDirectory(string zipFileName)
239        {
240            using (var zip = new ZipFile())
241            {
242                zip.FullScan = true;
243                zip.Initialize(zipFileName);
244                zip.Save(zipFileName);
245            }
246        }
247
248
249
250        /// <summary>
251        ///   Verify the password on a zip file.
252        /// </summary>
253        ///
254        /// <remarks>
255        ///   <para>
256        ///     Keep in mind that passwords in zipfiles are applied to
257        ///     zip entries, not to the entire zip file. So testing a
258        ///     zipfile for a particular password doesn't work in the
259        ///     general case. On the other hand, it's often the case
260        ///     that a single password will be used on all entries in a
261        ///     zip file. This method works for that case.
262        ///   </para>
263        ///   <para>
264        ///     There is no way to check a password without doing the
265        ///     decryption. So this code decrypts and extracts the given
266        ///     zipfile into <see cref="System.IO.Stream.Null"/>
267        ///   </para>
268        /// </remarks>
269        ///
270        /// <param name="zipFileName">The filename to of the zip file to fix.</param>
271        ///
272        /// <param name="password">The password to check.</param>
273        ///
274        /// <returns>a bool indicating whether the password matches.</returns>
275        public static bool CheckZipPassword(string zipFileName, string password)
276        {
277            // workitem 13664
278            bool success = false;
279            try
280            {
281                using (ZipFile zip1 = ZipFile.Read(zipFileName))
282                {
283                    foreach (var e in zip1)
284                    {
285                        if (!e.IsDirectory && e.UsesEncryption)
286                        {
287                            e.ExtractWithPassword(System.IO.Stream.Null, password);
288                        }
289                    }
290                }
291                success = true;
292            }
293            catch(Ionic.Zip.BadPasswordException) { }
294            return success;
295        }
296
297
298        /// <summary>
299        ///   Provides a human-readable string with information about the ZipFile.
300        /// </summary>
301        ///
302        /// <remarks>
303        ///   <para>
304        ///     The information string contains 10 lines or so, about each ZipEntry,
305        ///     describing whether encryption is in use, the compressed and uncompressed
306        ///     length of the entry, the offset of the entry, and so on. As a result the
307        ///     information string can be very long for zip files that contain many
308        ///     entries.
309        ///   </para>
310        ///   <para>
311        ///     This information is mostly useful for diagnostic purposes.
312        ///   </para>
313        /// </remarks>
314        public string Info
315        {
316            get
317            {
318                var builder = new System.Text.StringBuilder();
319                builder.Append(string.Format("          ZipFile: {0}\n", this.Name));
320                if (!string.IsNullOrEmpty(this._Comment))
321                {
322                    builder.Append(string.Format("          Comment: {0}\n", this._Comment));
323                }
324                if (this._versionMadeBy != 0)
325                {
326                    builder.Append(string.Format("  version made by: 0x{0:X4}\n", this._versionMadeBy));
327                }
328                if (this._versionNeededToExtract != 0)
329                {
330                    builder.Append(string.Format("needed to extract: 0x{0:X4}\n", this._versionNeededToExtract));
331                }
332
333                builder.Append(string.Format("       uses ZIP64: {0}\n", this.InputUsesZip64));
334
335                builder.Append(string.Format("     disk with CD: {0}\n", this._diskNumberWithCd));
336                if (this._OffsetOfCentralDirectory == 0xFFFFFFFF)
337                    builder.Append(string.Format("      CD64 offset: 0x{0:X16}\n", this._OffsetOfCentralDirectory64));
338                else
339                    builder.Append(string.Format("        CD offset: 0x{0:X8}\n", this._OffsetOfCentralDirectory));
340                builder.Append("\n");
341                foreach (ZipEntry entry in this._entries.Values)
342                {
343                    builder.Append(entry.Info);
344                }
345                return builder.ToString();
346            }
347        }
348
349
350    }
351
352}
Note: See TracBrowser for help on using the repository browser.