Ionic.Zip.BadCRCException error

Mar 3, 2009 at 3:51 PM
I create a zip file compressing the my documents folder. Success
I restore that same zip file. Success
I update that zip file. Success
I restore the updated zip file. Fail

Using 1.7.2.11

Stack trace:
Ionic.Zip.BadCrcException was unhandled
  Message="CRC error: the file being extracted appears to be corrupted. Expected 0x988D51D7, Actual 0x9F89C723"
  Source="Ionic.Zip"
  StackTrace:
       at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password) in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipEntry.cs:line 1865
       at Ionic.Zip.ZipEntry.Extract(String baseDirectory, Boolean overwrite) in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipEntry.cs:line 1414
       at Ionic.Zip.ZipFile.ExtractAll(String path, Boolean wantOverwrite) in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipFile.cs:line 5586
       at SMG_Backup.MainForm.ZipRestore(String SourceFile, String DestFolder) in C:\Users\jeffy.SELLETHICS\Documents\Visual Studio 2005\Projects\SMG Backup\SMG Backup\MainForm.vb:line 367
       at SMG_Backup.MainForm.restoreFileBTN_Click(Object sender, EventArgs e) in C:\Users\jeffy.SELLETHICS\Documents\Visual Studio 2005\Projects\SMG Backup\SMG Backup\MainForm.vb:line 349
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at SMG_Backup.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
Mar 3, 2009 at 6:15 PM
In doing more testing, this may have to do more with the update process (I was thinking restore orignially).
I can create a zip archive with success, update the archive with success (success on the surface anyway)...if I update the updated archive (in other words a second update) I get an arithmetic error.
So I'm guessing that the file structure is changing on the original zip archive after I update it the first time, which would explain why I cound not restore (original post) or update it a second time (this post).
A penny for your thoughts...

Stack trace on updating a second time:

System.OverflowException was unhandled
  Message="Arithmetic operation resulted in an overflow."
  Source="Ionic.Zip"
  StackTrace:
       at Ionic.Zip.ZipEntry.CopyThroughOneEntry(Stream outstream) in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipEntry.cs:line 3430
       at Ionic.Zip.ZipEntry.Write(Stream outstream) in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipEntry.cs:line 3242
       at Ionic.Zip.ZipFile.Save() in c:\dinoch\dev\dotnet\zip\releases\v1.7.2.10\src\DotNetZip\Zip Partial DLL\ZipFile.cs:line 2915
       at SMG_Backup.MainForm.ZipUpdate(String OriginalFile) in C:\Users\jeffy.SELLETHICS\Documents\Visual Studio 2005\Projects\SMG Backup\SMG Backup\MainForm.vb:line 197
       at SMG_Backup.MainForm.btnUpdate_Click(Object sender, EventArgs e) in C:\Users\jeffy.SELLETHICS\Documents\Visual Studio 2005\Projects\SMG Backup\SMG Backup\MainForm.vb:line 117
       at System.Windows.Forms.Control.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnClick(EventArgs e)
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
       at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(ApplicationContext context)
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
       at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
       at SMG_Backup.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
       at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
       at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
       at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
       at System.Activator.CreateInstance(ActivationContext activationContext)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
Coordinator
Mar 3, 2009 at 6:18 PM

Sounds like a reasonable theory Jeff.

What do you mean by "Restore the original file" ?

Does that mean you call  ZipFile.Read(), then add back in the file you had previously removed?

How big is that zip file? how many entries?

I will try some tests here.

 

 

Mar 3, 2009 at 6:33 PM
Edited Mar 3, 2009 at 6:40 PM
First test:
I create jeff.zip = success.
I restore jeff.zip = success.
I make changes to files/folders in My Documents, then update jeff.zip = success (on the surface).
I try to restore jeff.zip after the update and it fails.

Second test:
I create jeff.zip = success.
I make changes to files/folders in My Documents, then update jeff.zip = success (on the surface).
I make changes again to files/folders in My Documents, then update jeff.zip again = fail.

My code (for the most part):
Save zip archive-
            zipArchive.AddDirectory(SourceFolder)
            zipArchive.CompressionLevel = Zlib.CompressionLevel.LEVEL9_BEST_COMPRESSION
            zipArchive.UseZip64WhenSaving = Ionic.Zip.Zip64Option.Always
            zipArchive.TempFileFolder = txtFolderSave.Text
            zipArchive.Save(DestFile)
           
Extract (restore) archive-
            zipExtract = Zip.ZipFile.Read(SourceFile)
            zipExtract.ExtractAll(DestFolder, True)

Update the zip archive-
            zipFileUpdate = Zip.ZipFile.Read(OriginalFile)
            zipFileUpdate.UseZip64WhenSaving = Zip.Zip64Option.Always
            zipFileUpdate.CompressionLevel = Zlib.CompressionLevel.BEST_COMPRESSION
            zipFileUpdate.TempFileFolder = txtParBackup.Text.Substring(0, 3)
            zipFileUpdate.Save()

the rest of the update code-

 'pass 1, enumerate zip entries and mark them for removal if they no longer exist in sourcefolder
            Dim MarkFileRemove As New System.Collections.Generic.List(Of Zip.ZipEntry)
            For Each FileEntryRemove As Zip.ZipEntry In zipFileUpdate
                Dim PathNamePass1 As String = System.IO.Path.Combine(zipSource, FileEntryRemove.FileName)
                If Not System.IO.File.Exists(PathNamePass1) Then
                    MarkFileRemove.Add(FileEntryRemove)
                End If
            Next

            'remove entries from pass 1
            For Each RemoveFile As Zip.ZipEntry In MarkFileRemove
                zipFileUpdate.RemoveEntry(RemoveFile)
            Next

            'pass 2, enumerate files in source folder, if file doesn't exist in zip file, add them
            Dim AddNewSourceFile As New System.Collections.Generic.List(Of System.IO.FileInfo)
            Dim SourceDir As New IO.DirectoryInfo(zipSource)
            Dim AllFiles As IO.FileInfo() = SourceDir.GetFiles("*.*", SearchOption.AllDirectories)
            For Each ExistingFile As IO.FileInfo In AllFiles
                If Not zipFileUpdate.EntryFileNames.Contains(Replace(Replace(ExistingFile.FullName, zipSource & "\", string.Empty), "\", "/")) Then
                    AddNewSourceFile.Add(ExistingFile)
                End If
            Next

            'add entries from pass 2
            For Each AddNewFile As System.IO.FileInfo In AddNewSourceFile
                Dim PathToFile As String = AddNewFile.FullName
                Dim zipDirectoryPath As String = Replace(AddNewFile.Directory.FullName, zipSource, String.Empty)
                If zipDirectoryPath.StartsWith("\") = True Then
                    zipFileUpdate.AddItem(PathToFile, zipDirectoryPath.Substring(1))
                Else
                    zipFileUpdate.AddItem(PathToFile, zipDirectoryPath)
                End If
            Next

            'pass 3, enumerate zip entries, compare date to original file in source folder, update entry if necessary
            Dim CompareFile As New System.Collections.Generic.List(Of Zip.ZipEntry)
            For Each oldFileEntry As Zip.ZipEntry In zipFileUpdate
                Dim PathName As String = System.IO.Path.Combine(zipSource, oldFileEntry.FileName)
                If System.IO.File.Exists(PathName) Then
                    Dim infoReader As System.IO.FileInfo
                    infoReader = My.Computer.FileSystem.GetFileInfo(PathName)
                    If (oldFileEntry.LastModified.Date < infoReader.LastWriteTime.Date) Then
                        CompareFile.Add(oldFileEntry)
                    End If
                End If
            Next

            'add entries from pass 3
            For Each ReplaceFile As Zip.ZipEntry In CompareFile
                Dim PathToFile As String = System.IO.Path.Combine(zipSource, ReplaceFile.FileName)
                Dim zipDirectoryPath As String = System.IO.Path.GetDirectoryName(ReplaceFile.FileName)
                zipFileUpdate.RemoveEntry(ReplaceFile)
                zipFileUpdate.UpdateFile(PathToFile, zipDirectoryPath)
            Next

The zip archive (jeff.zip) is 192MB.


..I like Tomlin, ex-Bucs DB coach. Great motivator.
               
Coordinator
Mar 3, 2009 at 8:16 PM
Ok, let me have a look at your code.  I tried here with my own logic but couldn't get it to break.

ps: I like Tomlin, too.  He seems very wise, very sharp.
Mar 3, 2009 at 8:27 PM
I'm going thru my code as well. I can't be sure, but I don't remember this being an issue - not much has changed. Hmmmm...
Coordinator
Mar 3, 2009 at 8:45 PM
Ok, I was able to get an Arithmetic Overflow using code structured as above.
This seems like a bug in DotNetZip.  I'll look into it and see if I can track it down and fix it.
Mar 3, 2009 at 8:54 PM
Ahh..good (although not for you) - I was starting to think I was losing it...
I know my code structure isn't the greatest being a rookie, so I hope that isn't causing you too much headache.
---------------
(Speaking of rookie, Limas Sweed better step up next year. Ward is getting rough around the edges, Washington went to the Titans, and Holmes (whom I draft every FFL year - then ultimately trade when he's doing good) is inconsistent. I'm thinking they draft a WR.)
Coordinator
Mar 4, 2009 at 6:01 AM
Edited Mar 4, 2009 at 6:03 AM
Ha! I had Holmes this year in my FFL but he was spotty.  I totally agree with your assessment on the WR corps of the Steelers, though. Ward is on the decline I think.  Still a leader but his production is declining.

Ok, good news / bad news.  The good news is that I found and fixed the problem.
The bad news is that I made the changes to v1.8 I haven't yet ported them to v1.7. 

I'd like it if you can try it out on v1.8.1.7 and let me know if that fixes your problem.  In the meantime I will look into back-porting the changes to v1.7.
Also - the ability to include or exclude files in the things you are zipping up - I think you asked for that?  - that feature is also available in v1.8.  Check it out.
Coordinator
Mar 4, 2009 at 7:24 AM
OK, v1.7.2.12 includes the fix.  It's available now.
I'd like you to try it out, or the v1.8 version.  Or both if you like.
Only v1.8 gets the include-or-exclude-files-in-the-Add-or-Extract feature.
Mar 4, 2009 at 2:50 PM
Using 1.8.1.7 now and it seems to be just fine. Initial tests are successful so I'm going to test then roll out the app. I appreciate all the help, I really do.
-------
If you're interested, I'm commish of a Yahoo 10 team FFL - $65 entry, weekly payouts as well as division winner, champ and runner up payout. I have one person not returning..if you want more details let me know.
Mar 6, 2009 at 6:59 PM
Using 1.8.1.7 - how do you exclude a file using the zip.AddDirectory?
In example, excluding "*.pst" file(s). I was thinking there was a zip.addDirectory(source, filestoexclude) kind of thing..
Coordinator
Mar 6, 2009 at 9:47 PM
ZipFile.AddSelectedFiles("name != *.pst", MyDirectory, True)

True  means "recurse directories".