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 Password_BasicAddAndExtract()
        {
            int i;
            string[] Passwords = { null, "Password!", TestUtilities.GenerateRandomPassword(), "A" };

            Alienlab.Zlib.CompressionLevel[] compressionLevelOptions = {
                Alienlab.Zlib.CompressionLevel.None,
                Alienlab.Zlib.CompressionLevel.BestSpeed,
                Alienlab.Zlib.CompressionLevel.Default,
                Alienlab.Zlib.CompressionLevel.BestCompression,
            };

            for (int k = 0; k < compressionLevelOptions.Length; k++)
            {
                for (int j = 0; j < Passwords.Length; j++)
                {
                    TestContext.WriteLine("\n\n===================\nTrial ({0}) pw({1})", j, Passwords[j]);
                    string ZipFileToCreate = Path.Combine(TopLevelDir, String.Format("Password_BasicAddAndExtract-{0}-{1}.zip", k, j));
                    Assert.IsFalse(File.Exists(ZipFileToCreate), "The temporary zip file '{0}' already exists.", ZipFileToCreate);

                    Directory.SetCurrentDirectory(TopLevelDir);
                    string DirToZip = String.Format("zipthis-{0}-{1}", k, j);
                    Directory.CreateDirectory(DirToZip);

                    TestContext.WriteLine("\n---------------------creating files and computing checksums...");
                    int NumFilesToCreate = _rnd.Next(10) + 10;
                    string[] filenames = new string[NumFilesToCreate];
                    var checksums = new Dictionary<string, string>();
                    for (i = 0; i < NumFilesToCreate; i++)
                    {
                        filenames[i] = Path.Combine(DirToZip, String.Format("file{0:D3}.txt", i));
                        int sz = _rnd.Next(22000) + 3000;
                        //int sz = 1000;
                        var repeatedLine = String.Format("Line to Repeat... {0} {1} {2} filename: {3}", i, k, j, filenames[i]);
                        TestUtilities.CreateAndFillFileText(filenames[i], repeatedLine, sz);
                        string key = Path.GetFileName(filenames[i]);
                        checksums.Add(key, TestUtilities.GetCheckSumString(filenames[i]));
                        TestContext.WriteLine("  chk[{0}]={1}", key, checksums[key]);
                    }

                    TestContext.WriteLine("\n---------------------adding files to the archive...");

                    var sw = new StringWriter();
                    using (ZipFile zip = new ZipFile(ZipFileToCreate, sw))
                    {
                        zip.CompressionLevel = compressionLevelOptions[k];
                        zip.Password = Passwords[j];
                        zip.AddDirectory(Path.GetFileName(DirToZip));
                        zip.Save();
                    }
                    TestContext.WriteLine(sw.ToString());

                    Assert.AreEqual<int>(TestUtilities.CountEntries(ZipFileToCreate), NumFilesToCreate,
                            "The Zip file has an unexpected number of entries.");

                    TestContext.WriteLine("\n---------------------verifying checksums...");

                    using (ZipFile zip = ZipFile.Read(ZipFileToCreate))
                    {
                        foreach (ZipEntry e in zip)
                            TestContext.WriteLine("found entry: {0}", e.FileName);

                        var extractDir = String.Format("extract-{0}-{1}", k, j);
                        TestContext.WriteLine("  Extract with pw({0})", Passwords[j]);
                        foreach (ZipEntry e in zip)
                        {
                            e.ExtractWithPassword(extractDir, ExtractExistingFileAction.OverwriteSilently, Passwords[j]);
                            if (!e.IsDirectory)
                            {
                                byte[] c2 = TestUtilities.ComputeChecksum(Path.Combine(extractDir, e.FileName));
                                Assert.AreEqual<string>(checksums[e.FileName],
                                        TestUtilities.CheckSumToString(c2), "The checksum of the extracted file is incorrect.");
                            }
                        }
                    }
                    TestContext.WriteLine("\n");
                }
            }
        }
        public void Progress_ReadFile()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string  zipFileToCreate = Path.Combine(TopLevelDir, "Progress_ReadFile.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            using (ZipFile zip = new ZipFile())
            {
                zip.AddFiles(files);
                zip.Save(zipFileToCreate);
            }

            int count = TestUtilities.CountEntries(zipFileToCreate);
            Assert.IsTrue(count>0);

            var options = new ReadOptions {
                    StatusMessageWriter = new StringWriter(),
                    ReadProgress = ReadProgress1
            };
            using (ZipFile zip = ZipFile.Read(zipFileToCreate, options))
            {
                // this should be fine
                zip.RemoveEntry(zip[1]);
                zip.Save();
            }
            TestContext.WriteLine(options.StatusMessageWriter.ToString());
            Assert.AreEqual<Int32>(count, TestUtilities.CountEntries(zipFileToCreate)+1);
        }
        public void Password_UnsetEncryptionAfterSetPassword_wi13909_ZF()
        {
            // Verify that unsetting the Encryption property after
            // setting a Password results in no encryption being used.
            // This method tests ZipFile.
            string unusedPassword = TestUtilities.GenerateRandomPassword();
            int numTotalEntries = _rnd.Next(46)+653;
            string zipFileToCreate = "UnsetEncryption.zip";

            using (var zip = new ZipFile())
            {
                zip.Password = unusedPassword;
                zip.Encryption = EncryptionAlgorithm.None;

                for (int i=0; i < numTotalEntries; i++)
                {
                    if (_rnd.Next(7)==0)
                    {
                        string entryName = String.Format("{0:D5}", i);
                        zip.AddDirectoryByName(entryName);
                    }
                    else
                    {
                        string entryName = String.Format("{0:D5}.txt", i);
                        if (_rnd.Next(12)==0)
                        {
                            var block = TestUtilities.GenerateRandomAsciiString() + " ";
                            string contentBuffer = String.Format("This is the content for entry {0}", i);
                                int n = _rnd.Next(6) + 2;
                                for (int j=0; j < n; j++)
                                    contentBuffer += block;
                            byte[] buffer = System.Text.Encoding.ASCII.GetBytes(contentBuffer);
                            zip.AddEntry(entryName, contentBuffer);
                        }
                        else
                            zip.AddEntry(entryName, Stream.Null);
                    }
                }
                zip.Save(zipFileToCreate);
            }

            BasicVerifyZip(zipFileToCreate);
        }
        public void _Internal_Streams_ZipInput_Encryption(int fodderOption, int fileReadOption)
        {
            byte[] buffer = new byte[2048];
            int n;

            int[] fileCounts = { 1,
                                 2,
                                 _rnd.Next(8) + 6,
                                 _rnd.Next(18) + 16,
                                 _rnd.Next(48) + 56 };

            for (int m = 0; m < fileCounts.Length; m++)
            {
                string password = TestUtilities.GenerateRandomPassword();
                string dirToZip = String.Format("trial{0:D2}", m);
                if (!Directory.Exists(dirToZip)) Directory.CreateDirectory(dirToZip);

                int fileCount = fileCounts[m];
                TestContext.WriteLine("=====");
                TestContext.WriteLine("Trial {0} filecount={1}", m, fileCount);

                var files = (new Func<string[]>( () => {
                                 if (fodderOption == 0)
                                 {
                                     // zero length files
                                     var a = new string[fileCount];
                                     for (int i = 0; i < fileCount; i++)
                                         a[i] = CreateZeroLengthFile(i, dirToZip);
                                     return a;
                                 }

                                 if (fodderOption == 1)
                                     return TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);


                                 // mixed = some zero and some not
                                 var b = new string[fileCount];
                                 for (int i = 0; i < fileCount; i++)
                                 {
                                     if (_rnd.Next(3) == 0)
                                         b[i] = CreateZeroLengthFile(i, dirToZip);
                                     else
                                     {
                                         b[i] = Path.Combine(dirToZip, String.Format("nonzero{0:D4}.txt", i));
                                         TestUtilities.CreateAndFillFileText(b[i], _rnd.Next(60000) + 100);
                                     }
                                 }
                                 return b;
                             }))();


                for (int i = 0; i < crypto.Length; i++)
                {
                    EncryptionAlgorithm c = crypto[i];

                    string zipFileToCreate =
                        Path.Combine(TopLevelDir,
                                     String.Format("ZIS_Crypto.{0}.count.{1:D2}.{2}.zip",
                                                   c.ToString(), fileCounts[m], fodderOption));

                    // Create the zip archive
                    using (var zip = new ZipFile())
                    {
                        zip.Password = password;
                        zip.Encryption = c;
                        if (fodderOption > 2)
                        {
                            zip.AddDirectoryByName("subdir");
                            zip.AddDirectory(dirToZip, "subdir");
                        }
                        else
                            zip.AddDirectory(dirToZip);

                        zip.Save(zipFileToCreate);
                    }


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

                    // extract the files
                    string extractDir = String.Format("extract{0:D2}.{1:D2}", m, i);
                    TestContext.WriteLine("Extract to: {0}", extractDir);
                    Directory.CreateDirectory(extractDir);

                    var input = (new Func<ZipInputStream>( () => {
                                if (fileReadOption == 0)
                                {
                                    var raw = File.OpenRead(zipFileToCreate);
                                    return new ZipInputStream(raw);
                                }

                                return new ZipInputStream(zipFileToCreate);
                            }))();

                    using (input)
                    {
                        // set password if necessary
                        if (crypto[i] != EncryptionAlgorithm.None)
                            input.Password = password;

                        ZipEntry e;
                        while ((e = input.GetNextEntry()) != null)
                        {
                            TestContext.WriteLine("entry: {0}", e.FileName);
                            string outputPath = Path.Combine(extractDir, e.FileName);
                            if (e.IsDirectory)
                            {
                                // create the directory
                                Directory.CreateDirectory(outputPath);
                            }
                            else
                            {
                                // emit the file
                                using (var output = File.Create(outputPath))
                                {
                                    while ((n = input.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        output.Write(buffer, 0, n);
                                    }
                                }
                            }
                        }
                    }

                    string[] filesUnzipped = (fodderOption > 2)
                        ? Directory.GetFiles(Path.Combine(extractDir, "subdir"))
                        : Directory.GetFiles(extractDir);

                    // Verify the number of files extracted
                    Assert.AreEqual<int>(files.Length, filesUnzipped.Length,
                                         "Incorrect number of files extracted. ({0}!={1})", files.Length, filesUnzipped.Length);
                }
            }
        }
        private void _Internal_AddEntry_WriteDelegate(string[] files,
                                                      EncryptionAlgorithm crypto,
                                                      bool seekable,
                                                      int cycle,
                                                      string format,
                                                      int ignored)
        {
            int bufferSize = 2048;
            byte[] buffer = new byte[bufferSize];
            int n;

            for (int k = 0; k < compLevels.Length; k++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format(format, compLevels[k].ToString()));
                string password = TestUtilities.GenerateRandomPassword();

                using (var zip = new ZipFile())
                {
                    TestContext.WriteLine("=================================");
                    TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFileToCreate));
                    TestContext.WriteLine("Encryption({0})  Compression({1})  pw({2})",
                                          crypto.ToString(), compLevels[k].ToString(), password);

                    zip.Password = password;
                    zip.Encryption = crypto;
                    zip.CompressionLevel = compLevels[k];

                    foreach (var file in files)
                    {
                        zip.AddEntry(file, (name, output) =>
                            {
                                using (var input = File.OpenRead(name))
                                {
                                    while ((n = input.Read(buffer, 0, buffer.Length)) != 0)
                                    {
                                        output.Write(buffer, 0, n);
                                    }
                                }
                            });
                    }


                    if (!seekable)
                    {
                        // conditionally use a non-seekable output stream
                        using (var raw = File.Create(zipFileToCreate))
                        {
                            using (var ns = new Alienlab.Zip.Tests.NonSeekableOutputStream(raw))
                            {
                                zip.Save(ns);
                            }
                        }
                    }
                    else
                        zip.Save(zipFileToCreate);
                }

                BasicVerifyZip(Path.GetFileName(zipFileToCreate), password);

                Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                     "Trial ({0},{1}): The zip file created has the wrong number of entries.", cycle, k);
            }
        }
        public void UpdateZip_AddNewDirectory()
        {
            string zipFileToCreate = Path.Combine(TopLevelDir, "UpdateZip_AddNewDirectory.zip");

            String CommentOnArchive = "BasicTests::UpdateZip_AddNewDirectory(): This archive will be overwritten.";

            string newComment = "This comment has been OVERWRITTEN." + DateTime.Now.ToString("G");
            string dirToZip = Path.Combine(TopLevelDir, "zipup");

            int i, j;
            int entries = 0;
            string subdir = null;
            String filename = null;
            int subdirCount = _rnd.Next(4) + 4;
            for (i = 0; i < subdirCount; i++)
            {
                subdir = Path.Combine(dirToZip, "Directory." + i);
                Directory.CreateDirectory(subdir);

                int fileCount = _rnd.Next(3) + 3;
                for (j = 0; j < fileCount; j++)
                {
                    filename = Path.Combine(subdir, "file" + j + ".txt");
                    TestUtilities.CreateAndFillFileText(filename, _rnd.Next(12000) + 5000);
                    entries++;
                }
            }

            using (ZipFile zip = new ZipFile())
            {
                zip.AddDirectory(dirToZip);
                zip.Comment = CommentOnArchive;
                zip.Save(zipFileToCreate);
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), entries,
                    "The created Zip file has an unexpected number of entries.");

            BasicVerifyZip(zipFileToCreate);

            // Now create a new subdirectory and add that one
            subdir = Path.Combine(TopLevelDir, "NewSubDirectory");
            Directory.CreateDirectory(subdir);

            filename = Path.Combine(subdir, "newfile.txt");
            TestUtilities.CreateAndFillFileText(filename, _rnd.Next(12000) + 5000);
            entries++;

            using (ZipFile zip = new ZipFile(zipFileToCreate))
            {
                zip.AddDirectory(subdir);
                zip.Comment = newComment;
                // this will add entries into the existing zip file
                zip.Save();
            }

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

            using (ZipFile readzip = new ZipFile(zipFileToCreate))
            {
                Assert.AreEqual<string>(newComment,
                                        readzip.Comment,
                                        "The zip comment is incorrect.");
            }
        }
        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 Update_FromRoot_wi11988()
        {
            string zipFileToCreate = "FromRoot.zip";
            string dirToZip = "Fodder";
            var files = TestUtilities.GenerateFilesFlat(dirToZip);
            string windir = System.Environment.GetEnvironmentVariable("Windir");
            string substExe = Path.Combine(Path.Combine(windir, "system32"), "subst.exe");
            Assert.IsTrue(File.Exists(substExe), "subst.exe does not exist ({0})",
                          substExe);

            try
            {
                // create a subst drive
                this.Exec(substExe, "G: " + dirToZip);

                using (var zip = new ZipFile())
                {
                    zip.UpdateSelectedFiles("*.*", "G:\\", "", true);
                    zip.Save(zipFileToCreate);
                }

                Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                     files.Length);
                Assert.IsTrue(files.Length > 3);
                BasicVerifyZip(zipFileToCreate);
            }
            finally
            {
                // remove the virt drive
                this.Exec(substExe, "/D G:");
            }
        }
        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 Update_MultipleSavesWithRename_wi10544()
        {
            // select the name of the zip file
            string zipFileToCreate = Path.Combine(TopLevelDir, "Update_MultipleSaves_wi10319.zip");
            string entryName = "Entry1.txt";

            TestContext.WriteLine("Creating zip file... ");
            using (var zip = new ZipFile())
            {
                string firstline = "This is the first line in the Entry.\n";
                byte[] a = System.Text.Encoding.ASCII.GetBytes(firstline.ToCharArray());

                zip.AddEntry(entryName, a);
                zip.Save(zipFileToCreate);
            }

            int N = _rnd.Next(34) + 59;
            for (int i = 0; i < N; i++)
            {
                string tempZipFile = "AppendToEntry.zip.tmp" + i;

                TestContext.WriteLine("Update cycle {0}... ", i);
                using (var zip1 = ZipFile.Read(zipFileToCreate))
                {
                    using (var zip = new ZipFile())
                    {
                        zip.AddEntry(entryName, (name, stream) =>
                            {
                                var src = zip1[name].OpenReader();
                                int n;
                                byte[] b = new byte[2048];
                                while ((n = src.Read(b, 0, b.Length)) > 0)
                                    stream.Write(b, 0, n);

                                string update = String.Format("Updating zip file {0} at {1}\n", i, DateTime.Now.ToString("G"));
                                byte[] a = System.Text.Encoding.ASCII.GetBytes(update.ToCharArray());
                                stream.Write(a, 0, a.Length);
                            });

                        zip.Save(tempZipFile);
                    }
                }

                File.Delete(zipFileToCreate);
                System.Threading.Thread.Sleep(1400);
                File.Move(tempZipFile, zipFileToCreate);
            }

        }
        public void Update_MultipleSaves_wi10694()
        {
            string zipFileToCreate = "Update_MultipleSaves_wi10694.zip";
            var shortDir = "fodder";
            string subdir = Path.Combine(TopLevelDir, shortDir);
            string[] filesToZip = TestUtilities.GenerateFilesFlat(subdir);

            using (ZipFile zip1 = new ZipFile())
            {
                zip1.AddFiles(filesToZip, "Download");
                zip1.AddFiles(filesToZip, "other");
                zip1.Save(zipFileToCreate);
            }

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

            using (var zip2 = ZipFile.Read(zipFileToCreate))
            {
                var entries = zip2.Entries.Where(e => e.FileName.Contains("Download")).ToArray();
                //PART1 - Add directory and save
                zip2.AddDirectoryByName("XX");
                zip2.Save();

                //PART2 - Rename paths (not related to XX directory from above) and save
                foreach (var zipEntry in entries)
                {
                    zipEntry.FileName = zipEntry.FileName.Replace("Download", "Download2");
                }
                zip2.Save();
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate), 2 * filesToZip.Length,
                                 "Incorrect number of entries in the zip file.");
        }
        public void Update_MultipleSaves_wi10319()
        {
            string zipFileToCreate = "MultipleSaves_wi10319.zip";

            using (ZipFile _zipFile = new ZipFile(zipFileToCreate))
            {
                using (MemoryStream data = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(data))
                    {
                        writer.Write("Dit is een test string.");
                        writer.Flush();

                        data.Seek(0, SeekOrigin.Begin);
                        _zipFile.AddEntry("test.txt", data);
                        _zipFile.Save();
                        _zipFile.AddEntry("test2.txt", "Esta es un string de test");
                        _zipFile.Save();
                        _zipFile.AddEntry("test3.txt", "this is some content for the entry.");
                        _zipFile.Save();
                    }
                }
            }

            using (ZipFile _zipFile = new ZipFile(zipFileToCreate))
            {
                using (MemoryStream data = new MemoryStream())
                {
                    using (StreamWriter writer = new StreamWriter(data))
                    {
                        writer.Write("Dit is een andere test string.");
                        writer.Flush();

                        data.Seek(0, SeekOrigin.Begin);

                        _zipFile.UpdateEntry("test.txt", data);
                        _zipFile.Save();
                        _zipFile.UpdateEntry("test2.txt", "Esta es un otro string de test");
                        _zipFile.Save();
                        _zipFile.UpdateEntry("test3.txt", "This is another string for content.");
                        _zipFile.Save();

                    }
                }
            }
        }
        [TestMethod, Timeout(30 * 60 * 1000)]  // in ms.  30*60*100 == 30min
        public void ZipFile_PDOS_LeakTest_wi10030()
        {
            // Test memory growth over many many cycles.
            // There was a leak in the ParallelDeflateOutputStream, where
            // the PDOS was not being GC'd.  This test checks for that.
            //
            // If the error is present, this test will either timeout or
            // throw an InsufficientMemoryException (or whatever).  The
            // timeout occurs because GC begins to get verrrrry
            // sloooooow.  IF the error is not present, this test will
            // complete successfully, in about 20 minutes.
            //

            string zipFileToCreate = "ZipFile_PDOS_LeakTest_wi10030.zip";
            int nCycles = 4096;
            int nFiles = 3;
            int sizeBase = 384 * 1024;
            int sizeRange = 32 * 1024;
            int count = 0;
            byte[] buffer = new byte[1024];
            int n;

            // fill a couple memory streams with random text
            MemoryStream[] ms = new MemoryStream[nFiles];
            for (int i = 0; i < ms.Length; i++)
            {
                ms[i] = new MemoryStream();
                int sz = sizeBase + _rnd.Next(sizeRange);
                using (Stream rtg = new Alienlab.Zip.Tests.Utilities.RandomTextInputStream(sz))
                {
                    while ((n = rtg.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ms[i].Write(buffer, 0, n);
                    }
                }
            }
            buffer = null;

            OpenDelegate opener = (x) =>
                {
                    Stream s = ms[count % ms.Length];
                    s.Seek(0L, SeekOrigin.Begin);
                    count++;
                    return s;
                };

            CloseDelegate closer = (e, s) =>
                {
                    //s.Close();
                };

            string txrxLabel = "PDOS Leak Test";
            _txrx = TestUtilities.StartProgressMonitor("ZipFile_PDOS_LeakTest_wi10030", txrxLabel, "starting up...");

            TestContext.WriteLine("Testing for leaks....");

            _txrx.Send(String.Format("pb 0 max {0}", nCycles));
            _txrx.Send("pb 0 value 0");

            for (int x = 0; x < nCycles; x++)
            {
                if (x != 0 && x % 16 == 0)
                {
                    TestContext.WriteLine("Cycle {0}...", x);
                    string status = String.Format("status Cycle {0}/{1} {2:N0}%",
                                                  x + 1, nCycles,
                                                  ((x+1)/(0.01 * nCycles)));
                    _txrx.Send(status);
                }

                using (ZipFile zip = new ZipFile())
                {
                    zip.ParallelDeflateThreshold = 128 * 1024;
                    zip.CompressionLevel = Alienlab.Zlib.CompressionLevel.BestCompression;
                    //zip.SaveProgress += streams_SaveProgress;
                    for (int y = 0; y < nFiles; y++)
                    {
                        zip.AddEntry("Entry" + y + ".txt", opener, closer);
                    }
                    zip.Comment = "Produced at " + System.DateTime.UtcNow.ToString("G");
                    zip.Save(zipFileToCreate);
                }

                _txrx.Send("pb 0 step");
            }

            for (int i = 0; i < ms.Length; i++)
            {
                ms[i].Dispose();
                ms[i] = null;
            }
            ms = null;
        }
        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 ReadZip_OpenReader()
        {
            string[] passwords = { null, Path.GetRandomFileName(), "EE", "***()" };

            for (int j = 0; j < compLevels.Length; j++)
            {
                for (int k = 0; k < passwords.Length; k++)
                {
                    string zipFileToCreate = String.Format("ReadZip_OpenReader-{0}-{1}.zip", j, k);
                    //int entriesAdded = 0;
                    //String filename = null;
                    string dirToZip = String.Format("dirToZip.{0}.{1}", j, k);
                    var files = TestUtilities.GenerateFilesFlat(dirToZip);

                    using (ZipFile zip1 = new ZipFile())
                    {
                        zip1.CompressionLevel = compLevels[j];
                        zip1.Password = passwords[k];
                        zip1.AddDirectory(dirToZip,dirToZip);
                        zip1.Save(zipFileToCreate);
                    }

                    // Verify the files are in the zip
                    Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                         files.Length,
                                         String.Format("Trial ({0},{1})", j, k));

                    int i = 0;
                    ZipEntry e1 = null;
                    Func<Ionic.Crc.CrcCalculatorStream> opener = () => {
                        if (i == 0)
                            return e1.OpenReader();
                        if (i == 1)
                            return e1.OpenReader(passwords[k]);

                        e1.Password = passwords[k];
                        return e1.OpenReader();
                    };

                    // now extract the files and verify their contents
                    using (ZipFile zip2 = ZipFile.Read(zipFileToCreate))
                    {
                        for (i = 0; i < 3; i++)
                        {
                            // try once with Password set on ZipFile,
                            // another with password on the entry, and
                            // a third time with password passed into the OpenReader() method.
                            if (i == 0) zip2.Password = passwords[k];

                            foreach (string eName in zip2.EntryFileNames)
                            {
                                e1 = zip2[eName];
                                if (e1.IsDirectory) continue;

                                using (var s = opener())
                                {
                                    string outFile = String.Format("{0}.{1}.out", eName, i);
                                    int totalBytesRead = 0;
                                    using (var output = File.Create(outFile))
                                    {
                                        byte[] buffer = new byte[4096];
                                        int n;
                                        while ((n = s.Read(buffer, 0, buffer.Length)) > 0)
                                        {
                                            totalBytesRead += n;
                                            output.Write(buffer, 0, n);
                                        }
                                    }

                                    TestContext.WriteLine("CRC expected({0:X8}) actual({1:X8})",
                                                          e1.Crc, s.Crc);
                                    Assert.AreEqual<Int32>(s.Crc, e1.Crc,
                                                           string.Format("{0} :: CRC Mismatch", eName));
                                    Assert.AreEqual<Int32>(totalBytesRead, (int)e1.UncompressedSize,
                                                           string.Format("We read an unexpected number of bytes. ({0})", eName));
                                }
                            }
                        }
                    }
                }
            }
        }
        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 AddEntry_JitProvided()
        {
            for (int i = 0; i < crypto.Length; i++)
            {
                for (int k = 0; k < compLevels.Length; k++)
                {
                    string zipFileToCreate = String.Format("AddEntry_JitProvided.{0}.{1}.zip", i, k);
                    string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());
                    var files = TestUtilities.GenerateFilesFlat(dirToZip);
                    string password = Path.GetRandomFileName();

                    using (var zip = new ZipFile())
                    {
                        TestContext.WriteLine("=================================");
                        TestContext.WriteLine("Creating {0}...", Path.GetFileName(zipFileToCreate));
                        TestContext.WriteLine("Encryption({0})  Compression({1})  pw({2})",
                                              crypto[i].ToString(), compLevels[k].ToString(), password);

                        zip.Password = password;
                        zip.Encryption = crypto[i];
                        zip.CompressionLevel = compLevels[k];

                        foreach (var file in files)
                            zip.AddEntry(file,
                                         (name) => File.OpenRead(name),
                                         (name, stream) => stream.Close()
                                         );
                        zip.Save(zipFileToCreate);
                    }

                    if (crypto[i] == EncryptionAlgorithm.None)
                        BasicVerifyZip(zipFileToCreate);
                    else
                        BasicVerifyZip(zipFileToCreate, password);

                    Assert.AreEqual<int>(files.Length, TestUtilities.CountEntries(zipFileToCreate),
                                         "Trial ({0},{1}): The zip file created has the wrong number of entries.", i, k);
                }
            }
        }
        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 Progress_AddFiles()
        {
            Directory.SetCurrentDirectory(TopLevelDir);
            string  zipFileToCreate = Path.Combine(TopLevelDir, "Progress_AddFiles.zip");
            string dirToZip = Path.GetFileNameWithoutExtension(Path.GetRandomFileName());

            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            var sw = new StringWriter();
            using (ZipFile zip = new ZipFile(zipFileToCreate, sw))
            {
                zip.AddProgress += AddProgress1;
                zip.AddFiles(files);
                zip.Save();
            }
            TestContext.WriteLine(sw.ToString());

            int count = TestUtilities.CountEntries(zipFileToCreate);
            Assert.AreEqual<Int32>(count, files.Length);
        }
        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 Password_CheckZipPassword_wi13664()
        {
            string[] passwords = { null,
                                   "Password!",
                                   TestUtilities.GenerateRandomPassword(),
                                   "_" };

            string dirToZip = Path.Combine(TopLevelDir, "zipthis");
            int subdirCount;
            int entries = TestUtilities.GenerateFilesOneLevelDeep
                (TestContext, "wi13664", dirToZip, null, out subdirCount);
            string[] filesToZip = Directory.GetFiles("zipthis", "*.*", SearchOption.AllDirectories);

            Assert.AreEqual<int>(filesToZip.Length, entries,
                                 "Incorrect number of entries in the directory.");

            for (int j = 0; j < passwords.Length; j++)
            {
                string zipFileToCreate = Path.Combine(TopLevelDir, String.Format("Password_CheckZipPassword_wi13664-{0}.zip", j));

                // Create the zip archive
                using (ZipFile zip1 = new ZipFile())
                {
                    zip1.Password = passwords[j];
                    zip1.AddFiles(filesToZip, true, "");
                    zip1.Save(zipFileToCreate);
                }

                var r = ZipFile.CheckZipPassword(zipFileToCreate, passwords[j]);
                Assert.IsTrue(r, "Bad password in round {0}", j);
            }
        }
        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 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 ZipFile_JitStream_CloserTwice_wi10489()
        {
            int fileCount = 20 + _rnd.Next(20);
            string zipFileToCreate = "CloserTwice.zip";
            string dirToZip = "fodder";
            var files = TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);

            OpenDelegate opener = (name) =>
                {
                    TestContext.WriteLine("Opening {0}", name);
                    Stream s = File.OpenRead(Path.Combine(dirToZip,name));
                    return s;
                };

            CloseDelegate closer = (e, s) =>
                {
                    TestContext.WriteLine("Closing {0}", e);
                    s.Dispose();
                };

            TestContext.WriteLine("Creating zipfile {0}", zipFileToCreate);
            using (var zip = new ZipFile())
            {
                foreach (var file in files)
                {
                    zip.AddEntry(Path.GetFileName(file),opener,closer);
                }
                zip.Save(zipFileToCreate);
            }

            Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                 files.Length);

            BasicVerifyZip(zipFileToCreate);
        }
        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 JitStream_Update_wi13899()
        {
            int fileCount = 12 + _rnd.Next(16);
            string dirToZip = "fodder";
            var files = TestUtilities.GenerateFilesFlat(dirToZip, fileCount, 100, 72000);
            OpenDelegate opener = (name) =>
                {
                    TestContext.WriteLine("Opening {0}", name);
                    Stream s = File.OpenRead(Path.Combine(dirToZip,name));
                    return s;
                };

            CloseDelegate closer = (e, s) =>
                {
                    TestContext.WriteLine("Closing {0}", e);
                    s.Dispose();
                };

            // Two passes: first to call UpdateEntry() when no prior entry exists.
            // Second to call UpdateEntry when a prior entry exists.
            for (int j=0; j < 2; j++)
            {
                string zipFileToCreate = String.Format("wi13899-{0}.zip", j);

                TestContext.WriteLine("");
                TestContext.WriteLine("Creating zipfile {0}", zipFileToCreate);
                if (j!=0)
                {
                    using (var zip = new ZipFile(zipFileToCreate))
                    {
                        foreach (var file in files)
                        {
                            zip.AddEntry(Path.GetFileName(file), "This is the content for file " + file);
                        }
                        zip.Save();
                    }

                    Assert.AreEqual<int>(TestUtilities.CountEntries(zipFileToCreate),
                                         files.Length);

                    BasicVerifyZip(zipFileToCreate);

                    TestContext.WriteLine("Updating zipfile {0}", zipFileToCreate);
                }

                using (var zip = new ZipFile(zipFileToCreate))
                {
                    foreach (var file in files)
                    {
                        zip.UpdateEntry(Path.GetFileName(file), opener, closer);
                    }
                    zip.Save();
                }

                BasicVerifyZip(zipFileToCreate);
                // verify checksum here?
            }
        }
        public void SilentDeletion_wi10639()
        {
            string zipFileToCreate = "SilentDeletion.zip";
            string dirToZip = "dirToZip";
            string extractDir = "extracted";
            string password = TestUtilities.GenerateRandomPassword();
            string wrongPassword = "******";
            var files = TestUtilities.GenerateFilesFlat(dirToZip);

            TestContext.WriteLine("Creating the zip.");
            using (var zip = new ZipFile())
            {
                zip.Password = password;
                zip.AddFiles(files, dirToZip);
                zip.Save(zipFileToCreate);
            }

            TestContext.WriteLine("Extract one file with wrong password.");

             // pick a random entry to extract
            int ix = -1;
            string extractedFile = null;
            // perform two passes: first with correct password to extract the
            // file.  2nd with incorrect password to see if the file is
            // deleted.

            Directory.CreateDirectory(extractDir);
            for (int i=0; i < 2; i++)
            {
                try
                {
                    using (var zip = ZipFile.Read(zipFileToCreate))
                    {
                        if (i==0)
                        {
                            do
                            {
                                ix = this._rnd.Next(zip.Entries.Count);
                            }
                            while (zip[ix].IsDirectory);
                            TestContext.WriteLine("Selected entry: {0}", zip[ix].FileName);
                            extractedFile = Path.Combine(extractDir, zip[ix].FileName.Replace("/","\\"));
                            TestContext.WriteLine("name for extracted file: {0}", extractedFile);
                            Assert.IsFalse(File.Exists(extractedFile), "The file exists.");
                        }
                        TestContext.WriteLine("Cycle {0}: ExtractWithPassword()", i);
                        zip[ix].ExtractWithPassword(extractDir,
                                                    ExtractExistingFileAction.OverwriteSilently,
                                                    (i==0)? password : wrongPassword);
                    }
                }
                catch (Ionic.Zip.BadPasswordException bpe1)
                {
                    // only swallow exceptions on the first go-round
                    if (i==0) throw;
                }
                Assert.IsTrue(File.Exists(extractedFile), "Cycle {0}: The extracted file does not exist.", i);
            }
        }
        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.");
            }

        }