Search code examples
c#asp.netasp.net-mvcsharpziplibicsharpcode

ICSharpCode.SharpZipLib validate zip file


Using ICSharpCode.SharpZipLib for C#, how can I validate that the file being passed is actually a valid zip file (not something that has been right clicked and renamed as .zip)?

[HttpPost]
        public ActionResult Upload(HttpPostedFileBase fileData)
        {
                if (fileData != null && fileData.ContentLength > 0)
                {
                    if (Path.GetExtension(fileData.FileName) == ".zip")
                    {
                        var zipFile = Server.MapPath("~/Content/uploads/" + Path.GetFileName(fileData.FileName));
                        fileData.SaveAs(zipFile);

                        FileStream fs = System.IO.File.OpenRead(zipFile);
                        ZipFile zf = new ZipFile(fs);

                        foreach (ZipEntry zipEntry in zf)
                        {
                            if (zipEntry.Name.EndsWith(".htm") || zipEntry.Name.EndsWith(".html"))
                            {
                                 return Json(new { success = true });                             
                            }
                        }
                        fs.Close();
                        fs.Dispose();
                        System.IO.File.Delete(zipFile);
                    }
                    else
                    {
                        var fileName = Server.MapPath("~/Content/uploads/" + Path.GetFileName(fileData.FileName));
                        fileData.SaveAs(fileName);                           
                        return Json(new { success = true });
                    }
                }                    
                return Json(new { success = false });

    }

Solution

  • You can use the ZipFile.TestArchive method. Here is how it is declared in SharpZipLib:

    /// <summary>
    /// Test an archive for integrity/validity
    /// </summary>
    /// <param name="testData">Perform low level data Crc check</param>
    /// <returns>true if all tests pass, false otherwise</returns>
    /// <remarks>Testing will terminate on the first error found.</remarks>
    public bool TestArchive(bool testData)
    {
        return TestArchive(testData, TestStrategy.FindFirstError, null);
    }
    

    Usage example:

    ZipFile zipFile = new ZipFile("archive.zip");
    Console.WriteLine("Archive validation result: {0}", zipFile.TestArchive(true));