public void UpdateZip_RemoveEntry_ByLastModTime()
        {
            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_RemoveEntry_ByLastModTime.zip");
            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int numFilesToCreate = _rnd.Next(13) + 24;
            string filename = null;
            int entriesAdded = 0;
            for (int j = 0; j < numFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // Add the files to the zip, save the zip
            Directory.SetCurrentDirectory(TopLevelDir);
            int ix = 0;
            System.DateTime origDate = new System.DateTime(2007, 1, 15, 12, 1, 0);
            using (ZipFile zip1 = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                foreach (String f in filenames)
                {
                    ZipEntry e = zip1.AddFile(f, "");
                    e.LastModified = origDate + new TimeSpan(24 * 31 * ix, 0, 0);  // 31 days * number of entries
                    ix++;
                }
                zip1.Comment = "UpdateTests::UpdateZip_RemoveEntry_ByLastModTime(): This archive will soon be updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                "The Zip file has the wrong number of entries.");


            // selectively remove a few files in the zip archive
            var threshold = new TimeSpan(24 * 31 * (2 + _rnd.Next(ix - 12)), 0, 0);
            int numRemoved = 0;
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                // We cannot remove the entry from the list, within the context of
                // an enumeration of said list.
                // So we add the doomed entry to a list to be removed
                // later.
                // pass 1: mark the entries for removal
                var entriesToRemove = new List<ZipEntry>();
                foreach (ZipEntry e in zip2)
                {
                    if (e.LastModified < origDate + threshold)
                    {
                        entriesToRemove.Add(e);
                        numRemoved++;
                    }
                }

                // pass 2: actually remove the entry.
                foreach (ZipEntry zombie in entriesToRemove)
                    zip2.RemoveEntry(zombie);

                zip2.Comment = "UpdateTests::UpdateZip_RemoveEntry_ByLastModTime(): This archive has been updated.";
                zip2.Save();
            }

            // Verify the correct number of files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded - numRemoved,
                "Fie! The updated Zip file has the wrong number of entries.");

            // verify that all entries in the archive are within the threshold
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (ZipEntry e in zip3)
                    Assert.IsTrue((e.LastModified >= origDate + threshold),
                        "Merde. The updated Zip file has entries that lie outside the threshold.");
            }

        }
        public void UpdateZip_AddFile_ExistingFile_Error()
        {
            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_AddFile_ExistingFile_Error.zip");
            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int fileCount = _rnd.Next(3) + 4;
            string filename = null;
            int entriesAdded = 0;
            for (int j = 0; j < fileCount; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                TestUtilities.CreateAndFillFileText(filename, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // Add the files to the zip, save the zip
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                foreach (String f in filenames)
                    zip.AddFile(f, "");
                zip.Comment = "UpdateTests::UpdateZip_AddFile_ExistingFile_Error(): This archive will be updated.";
                zip.Save(zipFileToCreate);
            }

            // create and file a new file with text data
            int FileToUpdate = _rnd.Next(fileCount);
            filename = String.Format("file{0:D3}.txt", FileToUpdate);
            string repeatedLine = String.Format("**UPDATED** This file ({0}) was updated at {1}.",
                        filename,
                        System.DateTime.Now.ToString("G"));
            TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(21567) + 23872);

            // Try to again add that file in the zip archive. This
            // should fail.
            using (ZipFile z = ZipFile.Read(zipFileToCreate))
            {
                // Try Adding a file again.  THIS SHOULD THROW.
                ZipEntry e = z.AddFile(filename, "");
                z.Comment = "UpdateTests::UpdateZip_AddFile_ExistingFile_Error(): This archive has been updated.";
                z.Save();
            }
        }
        public void Password_Extract_WrongPassword()
        {
            string ZipFileToCreate = Path.Combine(TopLevelDir, "MultipleEntriesDifferentPasswords.zip");
            Assert.IsFalse(File.Exists(ZipFileToCreate), "The temporary zip file '{0}' already exists.", ZipFileToCreate);

            string SourceDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                SourceDir = Path.GetDirectoryName(SourceDir);

            Directory.SetCurrentDirectory(TopLevelDir);

            string[] filenames =
            {
                Path.Combine(SourceDir, "Tools\\Zipit\\bin\\Debug\\Zipit.exe"),
                Path.Combine(SourceDir, "Zip\\bin\\Debug\\Ionic.Zip.xml"),
            };

            string[] passwords =
            {
                    "12345678",
                    "0987654321",
            };

            int j = 0;
            using (ZipFile zip = new ZipFile(ZipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    zip.Password = passwords[j];
                    zip.AddFile(filenames[j], "");
                }
                zip.Save();
            }

            // now try to extract
            using (ZipFile zip = new ZipFile(ZipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                    zip[Path.GetFileName(filenames[j])].ExtractWithPassword("unpack", ExtractExistingFileAction.OverwriteSilently, "WrongPassword");
            }
        }
        public void Create_WithSpecifiedCodepage()
        {
            int i;
            CodepageTrial[] trials = {
                new CodepageTrial( "big5",   "弹出应用程序{0:D3}.bin", true),
                new CodepageTrial ("big5",   "您好{0:D3}.bin",        false),
                new CodepageTrial ("gb2312", "弹出应用程序{0:D3}.bin", false),
                new CodepageTrial ("gb2312", "您好{0:D3}.bin",        false),
                // insert other trials here.??
            };

            for (int k = 0; k < trials.Length; k++)
            {
                TestContext.WriteLine("");
                TestContext.WriteLine("---------------------Trial {0}....", k);
                TestContext.WriteLine("---------------------codepage: {0}....", trials[k].codepage);
                // create the subdirectory
                string subdir = Path.Combine(TopLevelDir, String.Format("trial{0}-files", k));
                Directory.CreateDirectory(subdir);

                // create a bunch of files
                int numFiles = _rnd.Next(3) + 3;
                string[] filesToZip = new string[numFiles];
                for (i = 0; i < numFiles; i++)
                {
                    filesToZip[i] = Path.Combine(subdir, String.Format(trials[k].filenameFormat, i));
                    TestUtilities.CreateAndFillFileBinary(filesToZip[i], _rnd.Next(5000) + 2000);
                }

                Directory.SetCurrentDirectory(subdir);

                // three cases: one for old-style
                // ProvisionalAlternateEncoding, one for "AsNecessary"
                // and one for "Always"
                for (int j=0; j < 3; j++)
                {

                    // select the name of the zip file
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("WithSpecifiedCodepage_{0}_{1}_{2}.zip",
                                                                                     k, j, trials[k].codepage));

                    TestContext.WriteLine("");
                    TestContext.WriteLine("---------------Creating zip, trial ({0},{1})....", k, j);

                    using (ZipFile zip1 = new ZipFile(zipFileToCreate))
                    {
                        switch (j)
                        {
                            case 0:
#pragma warning disable 618
                                zip1.ProvisionalAlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage);
#pragma warning restore 618
                                break;
                            case 1:
                                zip1.AlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage);
                                zip1.AlternateEncodingUsage = ZipOption.AsNecessary;
                                break;
                            case 2:
                                zip1.AlternateEncoding = System.Text.Encoding.GetEncoding(trials[k].codepage);
                                zip1.AlternateEncodingUsage = ZipOption.Always;
                                break;
                        }

                        for (i = 0; i < filesToZip.Length; i++)
                        {
                            TestContext.WriteLine("adding entry {0}", filesToZip[i]);
                            // use the local filename (not fully qualified)
                            ZipEntry e = zip1.AddFile(filesToZip[i], "");
                            e.Comment = String.Format("This entry was encoded in the {0} codepage", trials[k].codepage);
                        }
                        zip1.Save();
                    }

                    TestContext.WriteLine("\n---------------------Extracting....");
                    Directory.SetCurrentDirectory(TopLevelDir);

                    try
                    {
                        // verify the filenames are (or are not) unicode
                        var options = new ReadOptions {
                            Encoding = System.Text.Encoding.GetEncoding(trials[k].codepage)
                        };
                        using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options))
                        {
                            foreach (ZipEntry e in zip2)
                            {
                                TestContext.WriteLine("found entry {0}", e.FileName);
                                e.Extract(String.Format("trial{0}-{1}-{2}-extract", k, j, trials[k].codepage));
                            }
                        }
                    }
                    catch (Exception e1)
                    {
                        if (trials[k].exceptionExpected)
                            TestContext.WriteLine("caught expected exception");
                        else
                            throw new System.Exception("while extracting", e1);

                    }
                }

            }
            TestContext.WriteLine("\n---------------------Done.");
        }
        public void UpdateZip_RemoveAllEntries()
        {
            string password = "******" + TestUtilities.GenerateRandomLowerString(7);
            string filename = null;
            int entriesToBeAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_RemoveAllEntries.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int numFilesToCreate = _rnd.Next(13) + 14;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = String.Format("file{0:D3}.txt", j);
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                    filename);
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                entriesToBeAdded++;
            }

            // Add the files to the zip, save the zip
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                zip.Password = password;
                foreach (String f in filenames)
                    zip.AddFile(f, "");

                zip.Comment = "UpdateTests::UpdateZip_RemoveAllEntries(): This archive will be updated.";
                zip.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(entriesToBeAdded,
                                 TestUtilities.CountEntries(zipFileToCreate),
                                 "The Zip file has the wrong number of entries.");

            // remove all the entries from the zip archive
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                zip2.RemoveSelectedEntries("*.*");
                zip2.Comment = "This archive has been modified. All the entries have been removed.";
                zip2.Save();
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(0, TestUtilities.CountEntries(zipFileToCreate),
                "The Zip file has the wrong number of entries.");


        }
        public void UpdateZip_UpdateItem()
        {
            string filename = null;
            int entriesAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_UpdateItem.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create a bunch of files
            int numFilesToCreate = _rnd.Next(10) + 8;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                repeatedLine = String.Format("Content for Original file {0}",
                    Path.GetFileName(filename));
                TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // Create the zip file
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                foreach (String f in filenames)
                    zip1.AddFile(f, "");
                zip1.Comment = "UpdateTests::UpdateZip_UpdateItem(): This archive will be updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                "The Zip file has the wrong number of entries.");

            // create another subdirectory
            subdir = Path.Combine(TopLevelDir, "B");
            Directory.CreateDirectory(subdir);

            // create a bunch more files
            int newFileCount = numFilesToCreate + _rnd.Next(3) + 3;
            for (j = 0; j < newFileCount; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                repeatedLine = String.Format("Content for the updated file {0} {1}",
                    Path.GetFileName(filename),
                    System.DateTime.Now.ToString("yyyy-MM-dd"));
                TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(1000) + 2000);
                entriesAdded++;
            }

            // Update those files in the zip file
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("B");
                foreach (String f in filenames)
                    zip1.UpdateItem(f, "");
                zip1.Comment = "UpdateTests::UpdateZip_UpdateItem(): This archive has been updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), newFileCount,
                "The Zip file has the wrong number of entries.");

            // now extract the files and verify their contents
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s in zip3.EntryFileNames)
                {
                    repeatedLine = String.Format("Content for the updated file {0} {1}",
                        s,
                        System.DateTime.Now.ToString("yyyy-MM-dd"));
                    zip3[s].Extract("extract");

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(repeatedLine, sLine,
                            String.Format("The content of the Updated file ({0}) in the zip archive is incorrect.", s));
                }
            }
        }
        public void Extract_ImplicitPassword()
        {
            for (int k = 0; k < compLevels.Length; k++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Extract_ImplicitPassword-{0}.zip", k));
                Directory.SetCurrentDirectory(TopLevelDir);
                string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
                var files = TestUtilities.GenerateFilesFlat(dirToZip);
                string[] passwords = new string[files.Length];

                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.Comment = "Brick walls are there for a reason: to let you show how badly you want your goal.";
                    zip1.CompressionLevel = compLevels[k];
                    for (int i = 0; i < files.Length; i++)
                    {
                        passwords[i] = TestUtilities.GenerateRandomPassword();
                        zip1.Password = passwords[i];
                        TestContext.WriteLine("  Adding entry: {0} pw({1})", files[i], passwords[i]);
                        zip1.AddFile(files[i], Path.GetFileName(dirToZip));
                    }
                    zip1.Save(zipFileToCreate);
                }
                TestContext.WriteLine("\n");

                // extract using the entry from the enumerator
                int nExtracted = 0;
                using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                {
                    foreach (ZipEntry e in zip2)
                    {
                        e.Password = passwords[nExtracted];
                        TestContext.WriteLine("  Extracting entry: {0} pw({1})", e.FileName, passwords[nExtracted]);
                        e.Extract("unpack1");
                        nExtracted++;
                    }
                }

                Assert.AreEqual<Int32>(files.Length, nExtracted);

                // extract using the filename indexer
                nExtracted = 0;
                using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
                {
                    foreach (var name in zip3.EntryFileNames)
                    {
                        zip3.Password = passwords[nExtracted];
                        zip3[name].Extract("unpack2");
                        nExtracted++;
                    }
                }

                Assert.AreEqual<Int32>(files.Length, nExtracted);
            }
        }
        public void UpdateZip_RemoveEntry_ByFilename()
        {
            for (int k = 0; k < 2; k++)
            {
                int j;
                int entriesToBeAdded = 0;
                string filename = null;
                string repeatedLine = null;

                // select the name of the zip file
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("UpdateZip_RemoveEntry_ByFilename-{0}.zip", k));

                // create the subdirectory
                string subdir = Path.Combine(TopLevelDir, String.Format("A{0}", k));
                Directory.CreateDirectory(subdir);

                // create a bunch of files
                int numFilesToCreate = _rnd.Next(13) + 24;

                for (j = 0; j < numFilesToCreate; j++)
                {
                    filename = String.Format("file{0:D3}.txt", j);
                    repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                     filename);
                    TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                    entriesToBeAdded++;
                }

                // Add the files to the zip, save the zip.
                // in pass 2, remove one file, then save again.
                Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = new ZipFile())
                {
                    String[] filenames = Directory.GetFiles(String.Format("A{0}", k));

                    foreach (String f in filenames)
                        zip1.AddFile(f, "");

                    zip1.Comment = "UpdateTests::UpdateZip_RemoveEntry_ByFilename(): This archive will be updated.";
                    zip1.Save(zipFileToCreate);

                    // conditionally remove a single entry, on the 2nd trial
                    if (k == 1)
                    {
                        int chosen = _rnd.Next(filenames.Length);
                        zip1.RemoveEntry(zip1[chosen]);
                        zip1.Save();
                    }
                }

                // Verify the files are in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesToBeAdded - k,
                    "Trial {0}: the Zip file has the wrong number of entries.", k);

                if (k == 0)
                {
                    // selectively remove a few files in the zip archive
                    var filesToRemove = new List<string>();
                    int numToRemove = _rnd.Next(numFilesToCreate - 4) + 1;
                    using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                    {
                        for (j = 0; j < numToRemove; j++)
                        {
                            // select a new, uniquely named file to create
                            do
                            {
                                filename = String.Format("file{0:D3}.txt", _rnd.Next(numFilesToCreate));
                            } while (filesToRemove.Contains(filename));
                            // add this file to the list
                            filesToRemove.Add(filename);
                            zip2.RemoveEntry(filename);

                        }

                        zip2.Comment = "This archive has been modified. Some files have been removed.";
                        zip2.Save();
                    }


                    // extract all files, verify none should have been removed,
                    // and verify the contents of those that remain
                    using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
                    {
                        foreach (string s1 in zip3.EntryFileNames)
                        {
                            Assert.IsFalse(filesToRemove.Contains(s1),
                                           String.Format("File ({0}) was not expected.", s1));

                            zip3[s1].Extract("extract");
                            repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                             s1);

                            // verify the content of the updated file.
                            var sr = new StreamReader(Path.Combine("extract", s1));
                            string sLine = sr.ReadLine();
                            sr.Close();

                            Assert.AreEqual<string>(repeatedLine, sLine,
                                        String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));

                        }
                    }

                    // Verify the files are in the zip
                    Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                         entriesToBeAdded - filesToRemove.Count,
                                         "The updated Zip file has the wrong number of entries.");
                }
            }
        }
        public void WZA_RemoveEntryAndSave()
        {
            if (!WinZipIsPresent)
                throw new Exception("no winzip! [WZA_RemoveEntryAndSave]");

            // make a few text files
            string[] TextFiles = new string[5];
            for (int i = 0; i < TextFiles.Length; i++)
            {
                TextFiles[i] = Path.Combine(TopLevelDir, String.Format("TextFile{0}.txt", i));
                TestUtilities.CreateAndFillFileText(TextFiles[i], _rnd.Next(4000) + 5000);
            }
            TestContext.WriteLine(new String('=', 66));
            TestContext.WriteLine("RemoveEntryAndSave()");
            string password = Path.GetRandomFileName();
            for (int k = 0; k < 2; k++)
            {
                TestContext.WriteLine(new String('-', 55));
                TestContext.WriteLine("Trial {0}", k);
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("RemoveEntryAndSave-{0}.zip", k));

                // create the zip: add some files, and Save() it
                using (ZipFile zip = new ZipFile())
                {
                    if (k == 1)
                    {
                        TestContext.WriteLine("Specifying a password...");
                        zip.Password = password;
                        zip.Encryption = EncryptionAlgorithm.WinZipAes256;
                    }
                    for (int i = 0; i < TextFiles.Length; i++)
                        zip.AddFile(TextFiles[i], "");

                    zip.AddEntry("Readme.txt", "This is the content of the file. Ho ho ho!");
                    TestContext.WriteLine("Save...");
                    zip.Save(zipFileToCreate);
                }

                if (k == 1)
                    BasicVerifyZip(zipFileToCreate, password);

                // remove a file and re-Save
                using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                {
                    int entryToRemove = _rnd.Next(TextFiles.Length);
                    TestContext.WriteLine("Removing an entry...: {0}", Path.GetFileName(TextFiles[entryToRemove]));
                    zip2.RemoveEntry(Path.GetFileName(TextFiles[entryToRemove]));
                    zip2.Save();
                }

                // Verify the files are in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), TextFiles.Length,
                                     String.Format("Trial {0}: The Zip file has the wrong number of entries.", k));

                if (k == 1)
                    BasicVerifyZip(zipFileToCreate, password);
            }
        }
        public void WZA_Update_SwitchCompression()
        {
            if (!WinZipIsPresent)
                throw new Exception("no winzip! [WZA_Update_SwitchCompression]");

            string zipFileToCreate = "WZA_Update_SwitchCompression.zip";
            string password = TestUtilities.GenerateRandomPassword();

            TestContext.WriteLine("=======================================");
            TestContext.WriteLine("Creating file {0}", zipFileToCreate);
            TestContext.WriteLine("  Password:   {0}", password);
            int entries = _rnd.Next(21) + 5;

            string filename = null;
            var checksums = new Dictionary<string, string>();
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip1.CompressionLevel = Alienlab.Zlib.CompressionLevel.BestCompression;
                zip1.Password = password;

                for (int i = 0; i < entries; i++)
                {
                    if (_rnd.Next(2) == 1)
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.bin", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileBinary(filename, filesize);
                    }
                    else
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.txt", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileText(filename, filesize);
                    }
                    zip1.AddFile(filename, "");

                    var chk = TestUtilities.ComputeChecksum(filename);
                    checksums.Add(Path.GetFileName(filename), TestUtilities.CheckSumToString(chk));
                }

                zip1.Comment = String.Format("This archive uses Encryption({0}) password({1}) no compression.", zip1.Encryption, password);
                TestContext.WriteLine("{0}", zip1.Comment);
                TestContext.WriteLine("Saving the zip...");
                zip1.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate, password);

            TestContext.WriteLine("=======================================");
            TestContext.WriteLine("Updating the zip file");

            // Update the zip file
            using (ZipFile zip = ZipFile.Read(zipFileToCreate))
            {
                for (int j = 0; j < 5; j++)
                {
                    zip[j].Password = password;
                    zip[j].CompressionMethod = 0;
                }
                zip.Save(); // this should succeed
            }

        }
        public void WZA_CreateZip_EmptyPassword()
        {
            if (!WinZipIsPresent)
                throw new Exception("no winzip! [WZA_CreateZip_EmptyPassword]");

            // Using a blank password, eh?
            // Just what exactly is this *supposed* to do?
            //
            string zipFileToCreate = "WZA_CreateZip_EmptyPassword.zip";
            string password = "";

            TestContext.WriteLine("=======================================");
            TestContext.WriteLine("Creating file {0}", zipFileToCreate);
            TestContext.WriteLine("  Password:   '******'", password);
            int entries = _rnd.Next(21) + 5;

            string filename = null;
            var checksums = new Dictionary<string, string>();
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Encryption = EncryptionAlgorithm.WinZipAes256;
                zip1.Password = password;

                for (int i = 0; i < entries; i++)
                {
                    if (_rnd.Next(2) == 1)
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.bin", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileBinary(filename, filesize);
                    }
                    else
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.txt", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileText(filename, filesize);
                    }
                    zip1.AddFile(filename, "");

                    var chk = TestUtilities.ComputeChecksum(filename);
                    checksums.Add(Path.GetFileName(filename), TestUtilities.CheckSumToString(chk));
                }

                zip1.Comment = String.Format("This archive uses Encryption({0}) password({1}) no compression.", zip1.Encryption, password);
                zip1.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate, password);

            // validate all the checksums
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                foreach (ZipEntry e in zip2)
                {
                    if (!e.IsDirectory)
                    {
                        e.ExtractWithPassword("unpack", password);
                        string PathToExtractedFile = Path.Combine("unpack", e.FileName);
                        Assert.IsTrue(checksums.ContainsKey(e.FileName));

                        // verify the checksum of the file is correct
                        string expectedCheckString = checksums[e.FileName];
                        string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(PathToExtractedFile));
                        Assert.AreEqual<String>(expectedCheckString, actualCheckString, "Unexpected checksum on extracted filesystem file ({0}).", PathToExtractedFile);
                    }
                }
            }
        }
        public void WZA_CreateZip_NoPassword()
        {
            string zipFileToCreate = "WZA_CreateZip_NoPassword.zip";
            TestContext.WriteLine("Creating file {0}", zipFileToCreate);
            int entries = _rnd.Next(11) + 8;

            string filename = null;
            var checksums = new Dictionary<string, string>();
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Encryption = EncryptionAlgorithm.WinZipAes256;
                for (int i = 0; i < entries; i++)
                {
                    if (_rnd.Next(2) == 1)
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.bin", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileBinary(filename, filesize);
                    }
                    else
                    {
                        filename = Path.Combine(TopLevelDir, String.Format("Data{0}.txt", i));
                        int filesize = _rnd.Next(144000) + 5000;
                        TestUtilities.CreateAndFillFileText(filename, filesize);
                    }
                    zip1.AddFile(filename, "");

                    var chk = TestUtilities.ComputeChecksum(filename);
                    checksums.Add(Path.GetFileName(filename), TestUtilities.CheckSumToString(chk));
                }

                zip1.Comment = String.Format("This archive uses Encryption: {0}, no password!", zip1.Encryption);
                // With no password, we expect no encryption in the output.
                zip1.Save(zipFileToCreate);
            }

            #if NOT
            WinzipVerify(zipFileToCreate);

            // validate all the checksums
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                foreach (ZipEntry e in zip2)
                {
                    if (!e.IsDirectory)
                    {
                        e.Extract("unpack");
                        string PathToExtractedFile = Path.Combine("unpack", e.FileName);

                        Assert.IsTrue(e.Encryption == EncryptionAlgorithm.None);
                        Assert.IsTrue(checksums.ContainsKey(e.FileName));

                        // verify the checksum of the file is correct
                        string expectedCheckString = checksums[e.FileName];
                        string actualCheckString = TestUtilities.CheckSumToString(TestUtilities.ComputeChecksum(PathToExtractedFile));
                        Assert.AreEqual<String>(expectedCheckString, actualCheckString, "Unexpected checksum on extracted filesystem file ({0}).", PathToExtractedFile);
                    }
                }
            }
            #endif

        }
        public void Create_UnicodeEntries()
        {
            int i;
            string origComment = "This is a Unicode comment. "+
                                 "Chinese: 弹 出 应 用 程 序 "+
                                 "Norwegian/Danish: æøåÆØÅ. "+
                                 "Portugese: Configurações.";
            string[] formats = {
                "弹出应用程序{0:D3}.bin",
                "n.æøåÆØÅ{0:D3}.bin",
                "Configurações-弹出-ÆØÅ-xx{0:D3}.bin"
            };

            for (int k = 0; k < formats.Length; k++)
            {
                // create the subdirectory
                string subdir = Path.Combine(TopLevelDir, "files" + k);
                Directory.CreateDirectory(subdir);

                // create a bunch of files
                int numFilesToCreate = _rnd.Next(18) + 14;
                string[] filesToZip = new string[numFilesToCreate];
                for (i = 0; i < numFilesToCreate; i++)
                {
                    filesToZip[i] = Path.Combine(subdir, String.Format(formats[k], i));
                    TestUtilities.CreateAndFillFileBinary(filesToZip[i], _rnd.Next(5000) + 2000);
                }

                // create a zipfile twice, once using Unicode, once without
                for (int j = 0; j < 2; j++)
                {
                    // select the name of the zip file
                    string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Create_UnicodeEntries_{0}_{1}.zip", k, j));
                    Assert.IsFalse(File.Exists(zipFileToCreate), "The zip file '{0}' already exists.", zipFileToCreate);

                    TestContext.WriteLine("\n\nFormat {0}, trial {1}.  filename: {2}...", k, j, zipFileToCreate);
                    string dirInArchive = String.Format("{0}-{1}", Path.GetFileName(subdir), j);

                    using (ZipFile zip1 = new ZipFile())
                    {
#pragma warning disable 618
                        zip1.UseUnicodeAsNecessary = (j == 0);
#pragma warning restore 618
                        for (i = 0; i < filesToZip.Length; i++)
                        {
                            // use the local filename (not fully qualified)
                            ZipEntry e = zip1.AddFile(filesToZip[i], dirInArchive);
                            e.Comment = String.Format("This entry encoded with {0}", (j == 0) ? "unicode" : "the default code page.");
                        }
                        zip1.Comment = origComment;
                        zip1.Save(zipFileToCreate);
                    }

                    // Verify the number of files in the zip
                    Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Length,
                            "Incorrect number of entries in the zip file.");

                    i = 0;

                    // verify the filenames are (or are not) unicode

                    var options = new ReadOptions {
                        Encoding = (j == 0) ? System.Text.Encoding.UTF8 : ZipFile.DefaultEncoding
                    };
                    using (ZipFile zip2 = ZipFile.Read(zipFileToCreate, options))
                    {
                        foreach (ZipEntry e in zip2)
                        {
                            string fname = String.Format(formats[k], i);
                            if (j == 0)
                            {
                                Assert.AreEqual<String>(fname, Path.GetFileName(e.FileName));
                            }
                            else
                            {
                                Assert.AreNotEqual<String>(fname, Path.GetFileName(e.FileName));
                            }
                            i++;
                        }


                        // according to the spec,
                        // unicode is not supported on the zip archive comment!
                        // But this library won't enforce that.
                        // We will leave it up to the application.
                        // Assert.AreNotEqual<String>(origComment, zip2.Comment);

                    }
                }
            }
        }
        public void UpdateZip_RenameEntry()
        {
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
            var files = TestUtilities.GenerateFilesFlat(dirToZip,
                                                        _rnd.Next(13) + 24,
                                                        42 * 1024 + _rnd.Next(20000));

            // Two passes:  in pass 1, simply rename the file;
            // in pass 2, rename it so that it has a directory.
            // This shouldn't matter, but we test it anyway.
            for (int k = 0; k < 2; k++)
            {
                string zipFileToCreate = String.Format("UpdateZip_RenameEntry-{0}.zip", k);
                TestContext.WriteLine("-----------------------------");
                TestContext.WriteLine("{0}: Trial {1}, adding {2} files into '{3}'...",
                                      DateTime.Now.ToString("HH:mm:ss"),
                                      k,
                                      files.Length,
                                      zipFileToCreate);

                // Add the files to the zip, save the zip
                Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = new ZipFile())
                {
                    foreach (String f in files)
                        zip1.AddFile(f, "");
                    zip1.Comment = "This archive will be updated.";
                    zip1.Save(zipFileToCreate);
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                     files.Length,
                                     "the Zip file has the wrong number of entries.");

                // selectively rename a few files in the zip archive
                int renameCount = 0;
                using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                {
                    var toRename = new List<ZipEntry>();
                    while (toRename.Count < 2)
                    {
                        foreach (ZipEntry e in zip2)
                        {
                            if (_rnd.Next(2) == 1)
                                toRename.Add(e);
                        }
                    }

                    foreach (ZipEntry e in toRename)
                    {
                        var newname = (k == 0)
                            ? e.FileName + "-renamed"
                            : "renamed_files\\" + e.FileName;

                        TestContext.WriteLine("  renaming {0} to {1}", e.FileName, newname);
                        e.FileName = newname;
                        e.Comment = "renamed";
                        renameCount++;
                    }

                    zip2.Comment = String.Format("This archive has been modified. {0} files have been renamed.", renameCount);
                    zip2.Save();
                }


                // Extract all the files, verify that none have been removed,
                // and verify the names of the entries.
                int renameCount2 = 0;
                using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
                {
                    foreach (string s1 in zip3.EntryFileNames)
                    {
                        string dir = String.Format("extract{0}", k);
                        zip3[s1].Extract(dir);
                        string origFilename = Path.GetFileName((s1.Contains("renamed"))
                            ? s1.Replace("-renamed", "")
                            : s1);

                        if (zip3[s1].Comment == "renamed") renameCount2++;
                    }
                }

                Assert.AreEqual<int>(renameCount, renameCount2,
                    "The updated Zip file has the wrong number of renamed entries.");

                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                     files.Length,
                                     "Wrong number of entries.");
            }
        }
        public void Extract_MultiThreaded_wi6637()
        {
            int nConcurrentZipFiles = 5;
            for (int k = 0; k < 1; k++)
            {
                TestContext.WriteLine("\n-----------------------------\r\n{0}: Trial {1}...",
                      DateTime.Now.ToString("HH:mm:ss"),
                      k);

                Directory.SetCurrentDirectory(TopLevelDir);

                string[] zipFileToCreate = new string[nConcurrentZipFiles];
                for (int m = 0; m < nConcurrentZipFiles; m++)
                {
                    zipFileToCreate[m] = Path.Combine(TopLevelDir, String.Format("Extract_MultiThreaded-{0}-{1}.zip", k, m));
                    TestContext.WriteLine("  Creating file: {0}", zipFileToCreate[m]);
                    string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

                    var files = TestUtilities.GenerateFilesFlat(dirToZip);
                    TestContext.WriteLine("Zipping {0} files from dir '{1}'...", files.Length, dirToZip);

                    using (ZipFile zip1 = new ZipFile())
                    {
                        zip1.Comment = "Brick walls are there for a reason: to let you show how badly you want your goal.";
                        for (int i = 0; i < files.Length; i++)
                        {
                            TestContext.WriteLine("  Adding entry: {0}", files[i]);
                            zip1.AddFile(files[i], Path.GetFileName(dirToZip));
                        }
                        zip1.Save(zipFileToCreate[m]);
                    }
                    TestContext.WriteLine("\n");
                    BasicVerifyZip(zipFileToCreate[m]);
                }


                // multi-thread extract
                foreach (string fileName in zipFileToCreate)
                {
                    TestContext.WriteLine("queueing unzip for file: {0}", fileName);
                    System.Threading.ThreadPool.QueueUserWorkItem(processZip, fileName);
                }

                while (completedEntries != zipFileToCreate.Length)
                    System.Threading.Thread.Sleep(400);

                TestContext.WriteLine("done.");

            }
        }
        public void UpdateZip_UpdateEntryComment()
        {
            for (int k = 0; k < 2; k++)
            {
                int j;
                int entriesToBeAdded = 0;
                string filename = null;
                string repeatedLine = null;

                // select the name of the zip file
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("UpdateZip_UpdateEntryComment-{0}.zip", k));

                // create the subdirectory
                string subdir = Path.Combine(TopLevelDir, String.Format("A{0}", k));
                Directory.CreateDirectory(subdir);

                // create a bunch of files
                //int numFilesToCreate = _rnd.Next(15) + 18;
                int numFilesToCreate = _rnd.Next(5) + 3;

                TestContext.WriteLine("\n-----------------------------\r\n{0}: Trial {1}, adding {2} files into '{3}'...",
                    DateTime.Now.ToString("HH:mm:ss"),
                    k,
                    numFilesToCreate,
                    zipFileToCreate);

                for (j = 0; j < numFilesToCreate; j++)
                {
                    filename = String.Format("file{0:D3}.txt", j);
                    repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                     filename);

                    int filesize = _rnd.Next(34000) + 800;

                    TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename),
                                                        repeatedLine,
                                                        filesize);
                    entriesToBeAdded++;
                }

                // Add the files to the zip, save the zip
                Directory.SetCurrentDirectory(TopLevelDir);
                using (ZipFile zip1 = new ZipFile())
                {
                    String[] filenames = Directory.GetFiles(String.Format("A{0}", k));
                    foreach (String f in filenames)
                        zip1.AddFile(f, "");

                    zip1.Comment = "UpdateTests::UpdateZip_UpdateEntryComment(): This archive will be updated.";
                    zip1.Save(zipFileToCreate);
                }

                // Verify the files are in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesToBeAdded,
                    "the Zip file has the wrong number of entries.");

                // update the comments for a few files in the zip archive
                int updateCount = 0;
                using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                {
                    do
                    {
                        foreach (ZipEntry e in zip2)
                        {
                            if (_rnd.Next(2) == 1)
                            {
                                if (String.IsNullOrEmpty(e.Comment))
                                {
                                    e.Comment = "This is a new comment on entry " + e.FileName;
                                    updateCount++;
                                }
                            }
                        }
                    } while (updateCount < 2);
                    zip2.Comment = String.Format("This archive has been modified.  Comments on {0} entries have been inserted.", updateCount);
                    zip2.Save();
                }


                // Extract all files, verify that none have been removed,
                // and verify the contents of those that remain.
                int commentCount = 0;
                using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
                {
                    foreach (string s1 in zip3.EntryFileNames)
                    {
                        string dir = String.Format("extract{0}", k);
                        zip3[s1].Extract(dir);
                        repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                         s1);

                        // verify the content of the updated file.
                        var sr = new StreamReader(Path.Combine(dir, s1));
                        string sLine = sr.ReadLine();
                        sr.Close();

                        Assert.AreEqual<string>(repeatedLine, sLine,
                                    String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));

                        if (!String.IsNullOrEmpty(zip3[s1].Comment))
                        {
                            commentCount++;
                        }
                    }
                }

                Assert.AreEqual<int>(updateCount, commentCount,
                    "The updated Zip file has the wrong number of entries with comments.");

                // Verify the files are in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesToBeAdded,
                    "The updated Zip file has the wrong number of entries.");
            }
        }
        public void Extract_ExistingFile()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "Extract_ExistingFile.zip");
            string sourceDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                sourceDir = Path.GetDirectoryName(sourceDir);

            Directory.SetCurrentDirectory(TopLevelDir);

            string[] filenames =
                {
                    Path.Combine(sourceDir, "Tools\\Zipit\\bin\\Debug\\Zipit.exe"),
                    Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.dll"),
                    Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.pdb"),
                    Path.Combine(sourceDir, "Zip\\bin\\Debug\\Ionic.Zip.xml"),
                    //Path.Combine(SourceDir, "AppNote.txt")
                };

            int j = 0;
            using (ZipFile zip = new ZipFile())
            {
                for (j = 0; j < filenames.Length; j++)
                    zip.AddFile(filenames[j], "");
                zip.Comment = "This is a Comment On the Archive";
                zip.Save(zipFileToCreate);
            }


            BasicVerifyZip(zipFileToCreate);

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filenames.Length,
                                 "The zip file created has the wrong number of entries.");

            TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");
            TestContext.WriteLine("1. first extract - this should succeed");
            var options = new ReadOptions { StatusMessageWriter = new StringWriter() };
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    var f = Path.GetFileName(filenames[j]);
                    zip[f].Extract("unpack", ExtractExistingFileAction.Throw);
                }
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());

            TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");
            TestContext.WriteLine("2. extract again - DoNotOverwrite");
            options.StatusMessageWriter = new StringWriter();
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    var f = Path.GetFileName(filenames[j]);
                    zip[f].Extract("unpack", ExtractExistingFileAction.DoNotOverwrite);
                }
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());

            TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");
            TestContext.WriteLine("3. extract again - OverwriteSilently");
            options.StatusMessageWriter = new StringWriter();
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    var f = Path.GetFileName(filenames[j]);
                    zip[f].Extract("unpack", ExtractExistingFileAction.OverwriteSilently);
                }
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());

            TestContext.WriteLine("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");
            TestContext.WriteLine("4. extract again - InvokeExtractProgressEvent");
            options.StatusMessageWriter = new StringWriter();
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                zip.ExtractProgress += OverwriteDecider;
                for (j = 0; j < filenames.Length; j++)
                {
                    var f = Path.GetFileName(filenames[j]);
                    zip[f].Extract("unpack", ExtractExistingFileAction.InvokeExtractProgressEvent);
                }
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());
        }
        public void UpdateZip_RemoveEntry_ViaIndexer_WithPassword()
        {
            string password = TestUtilities.GenerateRandomPassword();
            string filename = null;
            int entriesToBeAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_RemoveEntry_ViaIndexer_WithPassword.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int numFilesToCreate = _rnd.Next(13) + 14;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = String.Format("file{0:D3}.txt", j);
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                    filename);
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                entriesToBeAdded++;
            }

            // Add the files to the zip, save the zip
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip = new ZipFile())
            {
                String[] filenames = Directory.GetFiles("A");
                zip.Password = password;
                foreach (String f in filenames)
                    zip.AddFile(f, "");

                zip.Comment = "UpdateTests::UpdateZip_OpenForUpdate_Password_RemoveViaIndexer(): This archive will be updated.";
                zip.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(entriesToBeAdded, TestUtilities.CountEntries(zipFileToCreate),
                "The Zip file has the wrong number of entries.");

            // selectively remove a few files in the zip archive
            var filesToRemove = new List<string>();
            int numToRemove = _rnd.Next(numFilesToCreate - 4);
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                for (j = 0; j < numToRemove; j++)
                {
                    // select a new, uniquely named file to create
                    do
                    {
                        filename = String.Format("file{0:D3}.txt", _rnd.Next(numFilesToCreate));
                    } while (filesToRemove.Contains(filename));
                    // add this file to the list
                    filesToRemove.Add(filename);

                    // remove the file from the zip archive
                    zip2.RemoveEntry(filename);
                }

                zip2.Comment = "This archive has been modified. Some files have been removed.";
                zip2.Save();
            }

            // extract all files, verify none should have been removed,
            // and verify the contents of those that remain
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s1 in zip3.EntryFileNames)
                {
                    Assert.IsFalse(filesToRemove.Contains(s1), String.Format("File ({0}) was not expected.", s1));

                    zip3[s1].ExtractWithPassword("extract", password);
                    repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                                     s1);

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s1));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(repeatedLine,
                                            sLine,
                                            String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));

                }
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                 entriesToBeAdded - filesToRemove.Count,
                                 "The updated Zip file has the wrong number of entries.");
        }
        public void Extended_CheckZip2()
        {
            string textToEncode =
                "Pay no attention to this: " +
                "We've read in the regular entry header, the extra field, and any " +
                "encryption header. The pointer in the file is now at the start of " +
                "the filedata, which is potentially compressed and encrypted.  Just " +
                "ahead in the file, there are _CompressedFileDataSize bytes of " +
                "data, followed by potentially a non-zero length trailer, " +
                "consisting of optionally, some encryption stuff (10 byte MAC for " +
                "AES), and then the bit-3 trailer (16 or 24 bytes). " +
                " " +
                "The encryption can be either PKZIP 2.0 (weak) encryption, or " +
                "WinZip-compatible AES encryption, which is considered to be " +
                "strong and for that reason is preferred.  In the WinZip AES " +
                "option, there are two different keystrengths supported: 128 bits " +
                "and 256 bits. " +
                " " +
                "The extra field, which I mentioned previously, specifies " +
                "additional metadata about the entry, which is strictly-speaking, " +
                "optional. These data are things like high-resolution timestamps, " +
                "data sizes that exceed 2^^32, and other encryption " +
                "possibilities.  In each case the library that reads a zip file " +
                "needs to be able to correctly deal with the various fields, " +
                "validating the values within them. " +
                " " +
                "Now, cross all that with the variety of usage patterns - creating a " +
                "zip, or reading, or extracting, or updating, or updating several " +
                "times. And also, remember that the metadata may change during " +
                "updates: an application can apply a password where none was used " +
                "previously, or it may wish to remove an entry from the zip entirely. " +
                " " +
                "The huge variety of combinations of possibilities is what makes " +
                "testing a zip library so challenging. " ;

            string testBin = TestUtilities.GetTestBinDir(CurrentDir);
            string fileToZip = Path.Combine(testBin, "Ionic.Zip.dll");

            for (int i = 0; i < crypto.Length; i++)
            {
                for (int j = 0; j < z64.Length; j++)
                {
                    string zipFile = String.Format("Extended-CheckZip2-{0}.{1}.zip", i, j);
                    string password = Path.GetRandomFileName();

                    TestContext.WriteLine("=================================");
                    TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFile));

                    string dir = Path.GetRandomFileName();
                    using (var zip = new ZipFile())
                    {
                        zip.Comment = String.Format("Encryption={0}  Zip64={1}  pw={2}",
                                                    crypto[i].ToString(), z64[j].ToString(), password);

                        zip.Encryption = crypto[i];
                        if (crypto[i] != EncryptionAlgorithm.None)
                        {
                            TestContext.WriteLine("Encryption({0})  Zip64({1}) pw({2})",
                                                  crypto[i].ToString(), z64[j].ToString(), password);
                            zip.Password = password;
                        }
                        else
                            TestContext.WriteLine("Encryption({0})  Zip64({1})",
                                                  crypto[i].ToString(), z64[j].ToString());

                        zip.UseZip64WhenSaving = z64[j];
                        int N = _rnd.Next(11) + 5;
                        for (int k = 0; k < N; k++)
                            zip.AddDirectoryByName(Path.GetRandomFileName());

                        zip.AddEntry("File1.txt", textToEncode);
                        zip.AddFile(fileToZip, Path.GetRandomFileName());
                        zip.Save(zipFile);
                    }

                    BasicVerifyZip(zipFile, password, false);

                    TestContext.WriteLine("Checking zip...");

                    using (var sw = new StringWriter())
                    {
                        bool result = ZipFile.CheckZip(zipFile, false, sw);
                        Assert.IsTrue(result, "Zip ({0}) does not check OK", zipFile);
                        var msgs = sw.ToString().Split('\n');
                        foreach (var msg in msgs)
                            TestContext.WriteLine("{0}", msg);
                    }
                    TestContext.WriteLine("OK");
                    TestContext.WriteLine("");
                }
            }
        }
        public void UpdateZip_AddFile_OldEntriesWithPassword()
        {
            string password = "******";
            string filename = null;
            int entriesAdded = 0;
            string repeatedLine = null;
            int j;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_AddFile_OldEntriesWithPassword.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create the files
            int numFilesToCreate = _rnd.Next(10) + 8;
            for (j = 0; j < numFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                    Path.GetFileName(filename));
                TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // Create the zip file
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Password = password;
                String[] filenames = Directory.GetFiles("A");
                foreach (String f in filenames)
                    zip1.AddFile(f, "");
                zip1.Comment = "UpdateTests::UpdateZip_AddFile_OldEntriesWithPassword(): This archive will be updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                "The Zip file has the wrong number of entries.");


            // Create a bunch of new files...
            var addedFiles = new List<string>();
            int numToUpdate = _rnd.Next(numFilesToCreate - 4);
            for (j = 0; j < numToUpdate; j++)
            {
                // select a new, uniquely named file to create
                filename = String.Format("newfile{0:D3}.txt", j);
                // create a new file, and fill that new file with text data
                repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                    filename, System.DateTime.Now.ToString("yyyy-MM-dd"));
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                addedFiles.Add(filename);
            }

            // add each one of those new files in the zip archive
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s in addedFiles)
                    zip2.AddFile(Path.Combine(subdir, s), "");
                zip2.Comment = "UpdateTests::UpdateZip_AddFile_OldEntriesWithPassword(): This archive has been updated.";
                zip2.Save();
            }

            // Verify the number of files in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                 entriesAdded + addedFiles.Count,
                                 "The Zip file has the wrong number of entries.");


            // now extract the newly-added files and verify their contents
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s in addedFiles)
                {
                    repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                        s, System.DateTime.Now.ToString("yyyy-MM-dd"));
                    zip3[s].Extract("extract");

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(repeatedLine, sLine,
                            String.Format("The content of the Updated file ({0}) in the zip archive is incorrect.", s));
                }
            }


            // extract all the other files and verify their contents
            using (ZipFile zip4 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s1 in zip4.EntryFileNames)
                {
                    bool addedLater = false;
                    foreach (string s2 in addedFiles)
                    {
                        if (s2 == s1) addedLater = true;
                    }
                    if (!addedLater)
                    {
                        zip4[s1].ExtractWithPassword("extract", password);
                        repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                            s1);

                        // verify the content of the updated file.
                        var sr = new StreamReader(Path.Combine("extract", s1));
                        string sLine = sr.ReadLine();
                        sr.Close();

                        Assert.AreEqual<string>(repeatedLine, sLine,
                                String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));
                    }
                }
            }
        }
        public void CompressTiff_Level9_wi8647()
        {
            string testBin = TestUtilities.GetTestBinDir(CurrentDir);

            string tifFile = Path.Combine(testBin, "Resources\\wi8647.tif");
            Assert.IsTrue(File.Exists(tifFile), "tif file does not exist ({0})", tifFile);

            byte[] chk1 = TestUtilities.ComputeChecksum(tifFile);
            string chk1String = TestUtilities.CheckSumToString(chk1);

            for (int x = 0; x < (int)(Ionic.Zlib.CompressionLevel.BestCompression); x++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir,
                                                      String.Format("CompressTiff_Level9-{0}.zip", x));
                byte[] chk2 = null;

                using (var zip = new ZipFile())
                {
                    zip.CompressionLevel = (Ionic.Zlib.CompressionLevel)x;
                    zip.AddFile(tifFile, "fodder");
                    zip.Save(zipFileToCreate);
                }

                BasicVerifyZip(zipFileToCreate);

                Assert.AreEqual<int>(1, TestUtilities.CountEntries(zipFileToCreate),
                                     "The zip file created has the wrong number of entries.");

                TestContext.WriteLine("---------------Reading {0}...", zipFileToCreate);
                string extractDir = String.Format("extract{0}", x);
                using (ZipFile zip = ZipFile.Read(zipFileToCreate))
                {
                    var e = zip[0];

                    TestContext.WriteLine(" Entry: {0}  c({1})  u({2})",
                                          e.FileName,
                                          e.CompressedSize,
                                          e.UncompressedSize);
                    e.Extract(extractDir);
                    string filename = Path.Combine(extractDir, e.FileName);
                    chk2 = TestUtilities.ComputeChecksum(filename);
                }

                string chk2String = TestUtilities.CheckSumToString(chk2);

                Assert.AreEqual<string>(chk1String, chk2String, "Cycle {0}, Checksums for ({1}) do not match.", x, tifFile);
                TestContext.WriteLine(" Cycle {0}: Checksums match ({1}).\n", x, chk1String);
            }
        }
        public void Password_MultipleEntriesDifferentPasswords()
        {
            string ZipFileToCreate = Path.Combine(TopLevelDir, "Password_MultipleEntriesDifferentPasswords.zip");
            Assert.IsFalse(File.Exists(ZipFileToCreate), "The temporary zip file '{0}' already exists.", ZipFileToCreate);

            string SourceDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                SourceDir = Path.GetDirectoryName(SourceDir);

            Directory.SetCurrentDirectory(TopLevelDir);

            string[] filenames =
            {
                Path.Combine(SourceDir, "Tools\\Zipit\\bin\\Debug\\Zipit.exe"),
                Path.Combine(SourceDir, "Zip\\bin\\Debug\\Ionic.Zip.xml"),
            };

            string[] checksums =
            {
                TestUtilities.GetCheckSumString(filenames[0]),
                TestUtilities.GetCheckSumString(filenames[1]),
            };

            string[] passwords =
            {
                    "12345678",
                    "0987654321",
            };

            int j = 0;
            using (ZipFile zip = new ZipFile(ZipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    zip.Password = passwords[j];
                    zip.AddFile(filenames[j], "");
                }
                zip.Save();
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(ZipFileToCreate), filenames.Length,
                    "The zip file created has the wrong number of entries.");

            using (ZipFile zip = new ZipFile(ZipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    zip[Path.GetFileName(filenames[j])].ExtractWithPassword("unpack", ExtractExistingFileAction.OverwriteSilently, passwords[j]);
                    string newpath = Path.Combine("unpack", filenames[j]);
                    string chk = TestUtilities.GetCheckSumString(newpath);
                    Assert.AreEqual<string>(checksums[j], chk, "File checksums do not match.");
                }
            }
        }
        public void UpdateZip_UpdateFile_DifferentPasswords()
        {
            string Password1 = "Whoofy1";
            string Password2 = "Furbakl1";
            string filename = null;
            int entriesAdded = 0;
            int j = 0;
            string repeatedLine;

            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_UpdateFile_DifferentPasswords.zip");

            // create the subdirectory
            string subdir = Path.Combine(TopLevelDir, "A");
            Directory.CreateDirectory(subdir);

            // create a bunch of files
            int NumFilesToCreate = _rnd.Next(13) + 14;
            for (j = 0; j < NumFilesToCreate; j++)
            {
                filename = Path.Combine(subdir, String.Format("file{0:D3}.txt", j));
                repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                      Path.GetFileName(filename));
                TestUtilities.CreateAndFillFileText(filename, repeatedLine, _rnd.Next(34000) + 5000);
                entriesAdded++;
            }

            // create the zip archive
            Directory.SetCurrentDirectory(TopLevelDir);
            using (ZipFile zip1 = new ZipFile())
            {
                zip1.Password = Password1;
                String[] filenames = Directory.GetFiles("A");
                foreach (String f in filenames)
                    zip1.AddFile(f, "");
                zip1.Comment = "UpdateTests::UpdateZip_UpdateFile_DifferentPasswords(): This archive will be updated.";
                zip1.Save(zipFileToCreate);
            }

            // Verify the files are in the zip
            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entriesAdded,
                "The Zip file has the wrong number of entries.");

            // create another subdirectory
            subdir = Path.Combine(TopLevelDir, "updates");
            Directory.CreateDirectory(subdir);

            // Create a bunch of new files, in that new subdirectory
            var UpdatedFiles = new List<string>();
            int NumToUpdate = _rnd.Next(NumFilesToCreate - 4);
            for (j = 0; j < NumToUpdate; j++)
            {
                // select a new, uniquely named file to create
                do
                {
                    filename = String.Format("file{0:D3}.txt", _rnd.Next(NumFilesToCreate));
                } while (UpdatedFiles.Contains(filename));
                // create a new file, and fill that new file with text data
                repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                    filename, System.DateTime.Now.ToString("yyyy-MM-dd"));
                TestUtilities.CreateAndFillFileText(Path.Combine(subdir, filename), repeatedLine, _rnd.Next(34000) + 5000);
                UpdatedFiles.Add(filename);
            }

            // update those files in the zip archive
            using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
            {
                zip2.Password = Password2;
                foreach (string s in UpdatedFiles)
                    zip2.UpdateFile(Path.Combine(subdir, s), "");
                zip2.Comment = "UpdateTests::UpdateZip_UpdateFile_DifferentPasswords(): This archive has been updated.";
                zip2.Save();
            }

            // extract those files and verify their contents
            using (ZipFile zip3 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s in UpdatedFiles)
                {
                    repeatedLine = String.Format("**UPDATED** This file ({0}) has been updated on {1}.",
                        s, System.DateTime.Now.ToString("yyyy-MM-dd"));
                    zip3[s].ExtractWithPassword("extract", Password2);

                    // verify the content of the updated file.
                    var sr = new StreamReader(Path.Combine("extract", s));
                    string sLine = sr.ReadLine();
                    sr.Close();

                    Assert.AreEqual<string>(sLine, repeatedLine,
                            String.Format("The content of the Updated file ({0}) in the zip archive is incorrect.", s));
                }
            }

            // extract all the other files and verify their contents
            using (ZipFile zip4 = ZipFile.Read(zipFileToCreate))
            {
                foreach (string s1 in zip4.EntryFileNames)
                {
                    bool wasUpdated = false;
                    foreach (string s2 in UpdatedFiles)
                    {
                        if (s2 == s1) wasUpdated = true;
                    }
                    if (!wasUpdated)
                    {
                        // use original password
                        zip4[s1].ExtractWithPassword("extract", Password1);
                        repeatedLine = String.Format("This line is repeated over and over and over in file {0}",
                            s1);

                        // verify the content of the updated file.
                        var sr = new StreamReader(Path.Combine("extract", s1));
                        string sLine = sr.ReadLine();
                        sr.Close();

                        Assert.AreEqual<string>(repeatedLine, sLine,
                                String.Format("The content of the originally added file ({0}) in the zip archive is incorrect.", s1));
                    }
                }
            }
        }
        public void Password_AddEntryWithPasswordToExistingZip()
        {
            string zipFileToCreate = "AddEntryWithPasswordToExistingZip.zip";
            string dnzDir = CurrentDir;
            for (int i = 0; i < 3; i++)
                dnzDir = Path.GetDirectoryName(dnzDir);

            string[] filenames =
            {
                Path.Combine(dnzDir, "Tools\\Zipit\\bin\\Debug\\Zipit.exe"),
                Path.Combine(dnzDir, "Zip\\bin\\Debug\\Ionic.Zip.xml"),
            };

            string[] checksums =
            {
                TestUtilities.GetCheckSumString(filenames[0]),
                TestUtilities.GetCheckSumString(filenames[1]),
            };

            int j = 0;
            using (ZipFile zip = new ZipFile(zipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                    zip.AddFile(filenames[j], "");
                zip.Save();
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), 2,
                    "wrong number of entries.");

            string fileX = Path.Combine(dnzDir, "Tools\\Unzip\\bin\\debug\\unzip.exe");
            string checksumX = TestUtilities.GetCheckSumString(fileX);
            string password = TestUtilities.GenerateRandomPassword() + "!";
            using (ZipFile zip = new ZipFile(zipFileToCreate))
            {
                zip.Password = password;
                zip.AddFile(fileX, "");
                zip.Save();
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), 3,
                    "wrong number of entries.");

            string unpackDir = "unpack";
            string newpath, chk, baseName;
            using (ZipFile zip = new ZipFile(zipFileToCreate))
            {
                for (j = 0; j < filenames.Length; j++)
                {
                    baseName = Path.GetFileName(filenames[j]);
                    zip[baseName].Extract(unpackDir, ExtractExistingFileAction.OverwriteSilently);
                    newpath = Path.Combine(unpackDir, filenames[j]);
                    chk = TestUtilities.GetCheckSumString(newpath);
                    Assert.AreEqual<string>(checksums[j], chk, "Checksums do not match.");
                }

                baseName = Path.GetFileName(fileX);

                zip[baseName].ExtractWithPassword(unpackDir,
                                                  ExtractExistingFileAction.OverwriteSilently,
                                                  password);

                newpath = Path.Combine(unpackDir, fileX);
                chk = TestUtilities.GetCheckSumString(newpath);
                Assert.AreEqual<string>(checksumX, chk, "Checksums do not match.");
            }
        }
        public void Create_UnicodeEntries_Mixed()
        {
            var filesToZip = _CreateUnicodeFiles();

            // Using those files create a zipfile 4 times:
            // cycle 0 - UseUnicodeAsNecessary
            // cycle 1 - Nothing
            // cycle 2 - AlternateEncoding = UTF8, AlternateEncodingUsage = Always
            // cycle 3 - AlternateEncoding = UTF8, AlternateEncodingUsage = AsNecessary
            for (int j = 0; j < 4; j++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Archive-{0}.zip", j));
                Assert.IsFalse(File.Exists(zipFileToCreate), "The file already exists ({0}).", zipFileToCreate);

                using (ZipFile zip1 = new ZipFile(zipFileToCreate))
                {
                    switch (j)
                    {
#pragma warning disable 618
                        case 0:
                            zip1.UseUnicodeAsNecessary = (j == 0);
                            break;
#pragma warning restore 618
                        case 1:
                            // do nothing
                            break;
                        case 2:
                            zip1.AlternateEncoding = System.Text.Encoding.UTF8;
                            zip1.AlternateEncodingUsage = ZipOption.Always;
                            break;
                        case 3:
                            zip1.AlternateEncoding = System.Text.Encoding.UTF8;
                            zip1.AlternateEncodingUsage = ZipOption.AsNecessary;
                            break;
                    }
                    foreach (var fileToZip in filesToZip)
                    {
                        zip1.AddFile(fileToZip, "");
                    }
                    zip1.Save();
                }

                // Verify the number of files in the zip
                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), filesToZip.Count,
                        "Incorrect number of entries in the zip file.");

                _CheckUnicodeZip(zipFileToCreate, j);
            }
        }