Beispiel #1
0
        /// <summary>
        /// Test an archive for integrity/validity
        /// </summary>
        /// <param name="testData">Perform low level data Crc check</param>
        /// <param name="strategy">The <see cref="TestStrategy"></see> to apply.</param>
        /// <param name="resultHandler">The <see cref="ZipTestResultHandler"></see> handler to call during testing.</param>
        /// <returns>true if all tests pass, false otherwise</returns>
        public bool TestArchive(bool testData, TestStrategy strategy, ZipTestResultHandler resultHandler)
        {
            TestStatus status = new TestStatus(this);

            if ( resultHandler != null ) {
                resultHandler(status, null);
            }

            HeaderTest test = testData ? (HeaderTest.Header | HeaderTest.Extract) : HeaderTest.Header;

            bool testing = true;

            try {
                int entryIndex = 0;

                while ( testing && (entryIndex < Count) ) {
                    if ( resultHandler != null ) {
                        status.SetEntry(this[entryIndex]);
                        status.SetOperation(TestOperation.EntryHeader);
                        resultHandler(status, null);
                    }

                    try	{
                        TestLocalHeader(this[entryIndex], test);
                    }
                    catch(ZipException ex) {
                        status.AddError();

                        if ( resultHandler != null ) {
                            resultHandler(status,
                                string.Format("Exception during test - '{0}'", ex.Message));
                        }

                        if ( strategy == TestStrategy.FindFirstError ) {
                            testing = false;
                        }
                    }

                    if ( testing && testData && this[entryIndex].IsFile ) {
                        if ( resultHandler != null ) {
                            status.SetOperation(TestOperation.EntryData);
                            resultHandler(status, null);
                        }

                        Stream entryStream = this.GetInputStream(this[entryIndex]);

                        Crc32 crc = new Crc32();
                        byte[] buffer = new byte[4096];
                        long totalBytes = 0;
                        int bytesRead;
                        while ((bytesRead = entryStream.Read(buffer, 0, buffer.Length)) > 0) {
                            crc.Update(buffer, 0, bytesRead);

                            if ( resultHandler != null ) {
                                totalBytes += bytesRead;
                                status.SetBytesTested(totalBytes);
                                resultHandler(status, null);
                            }
                        }

                        if (this[entryIndex].Crc != crc.Value) {
                            status.AddError();

                            if ( resultHandler != null ) {
                                resultHandler(status, "CRC mismatch");
                            }

                            if ( strategy == TestStrategy.FindFirstError ) {
                                testing = false;
                            }
                        }
                    }

                    if ( resultHandler != null ) {
                        status.SetOperation(TestOperation.EntryComplete);
                        resultHandler(status, null);
                    }

                    entryIndex += 1;
                }

                if ( resultHandler != null ) {
                    status.SetOperation(TestOperation.MiscellaneousTests);
                    resultHandler(status, null);
                }

                // TODO: the 'Corrina Johns' test where local headers are missing from
                // the central directory.  They are therefore invisible to many archivers.
            }
            catch (Exception ex) {
                status.AddError();

                if ( resultHandler != null ) {
                    resultHandler(status, string.Format("Exception during test - '{0}'", ex.Message));
                }
            }

            if ( resultHandler != null ) {
                status.SetOperation(TestOperation.Complete);
                status.SetEntry(null);
                resultHandler(status, null);
            }

            return (status.ErrorCount == 0);
        }
Beispiel #2
0
 public bool TestArchive(bool testData, 
     TestStrategy strategy = TestStrategy.FindFirstError, 
     ZipTestResultHandler resultHandler = null)
 {
     if (_isDisposed)
     {
         throw new ObjectDisposedException("ZipFile");
     }
     var status = new TestStatus(this);
     resultHandler?.Invoke(status, null);
     var tests = testData ? (HeaderTest.Header | HeaderTest.Extract) : HeaderTest.Header;
     var flag = true;
     try
     {
         for (var i = 0; flag && (i < Count); i++)
         {
             if (resultHandler != null)
             {
                 status.SetEntry(this[i]);
                 status.SetOperation(TestOperation.EntryHeader);
                 resultHandler(status, null);
             }
             try
             {
                 TestLocalHeader(this[i], tests);
             }
             catch (ZipException exception)
             {
                 status.AddError();
                 resultHandler?.Invoke(status, $"Exception during test - '{exception.Message}'");
                 if (strategy == TestStrategy.FindFirstError)
                 {
                     flag = false;
                 }
             }
             if ((flag && testData) && this[i].IsFile)
             {
                 if (resultHandler != null)
                 {
                     status.SetOperation(TestOperation.EntryData);
                     resultHandler(status, null);
                 }
                 var crc = new Crc32();
                 using (var stream = GetInputStream(this[i]))
                 {
                     int num3;
                     var buffer = new byte[DefaultBufferSize];
                     var num2 = 0L;
                     while ((num3 = stream.Read(buffer, 0, buffer.Length)) > 0)
                     {
                         crc.Update(buffer, 0, num3);
                         if (resultHandler != null)
                         {
                             num2 += num3;
                             status.SetBytesTested(num2);
                             resultHandler(status, null);
                         }
                     }
                 }
                 if (this[i].Crc != crc.Value)
                 {
                     status.AddError();
                     resultHandler?.Invoke(status, "CRC mismatch");
                     if (strategy == TestStrategy.FindFirstError)
                     {
                         flag = false;
                     }
                 }
                 if ((this[i].Flags & 8) != 0)
                 {
                     var stream2 = new ZipHelperStream(_baseStream);
                     var data = new DescriptorData();
                     stream2.ReadDataDescriptor(this[i].LocalHeaderRequiresZip64, data);
                     if (this[i].Crc != data.Crc)
                     {
                         status.AddError();
                     }
                     if (this[i].CompressedSize != data.CompressedSize)
                     {
                         status.AddError();
                     }
                     if (this[i].Size != data.Size)
                     {
                         status.AddError();
                     }
                 }
             }
             if (resultHandler != null)
             {
                 status.SetOperation(TestOperation.EntryComplete);
                 resultHandler(status, null);
             }
         }
         if (resultHandler != null)
         {
             status.SetOperation(TestOperation.MiscellaneousTests);
             resultHandler(status, null);
         }
     }
     catch (Exception exception2)
     {
         status.AddError();
         resultHandler?.Invoke(status, $"Exception during test - '{exception2.Message}'");
     }
     if (resultHandler != null)
     {
         status.SetOperation(TestOperation.Complete);
         status.SetEntry(null);
         resultHandler(status, null);
     }
     return (status.ErrorCount == 0);
 }