Files
UnrealEngine/Engine/Source/ThirdParty/DotNetZip/Zip Tests/PasswordTests.cs
2025-05-18 13:04:45 +08:00

529 lines
21 KiB
C#

// PasswordTests.cs
// ------------------------------------------------------------------
//
// Copyright (c) 2008-2011 Dino Chiesa .
// All rights reserved.
//
// This code module is part of DotNetZip, a zipfile class library.
//
// ------------------------------------------------------------------
//
// This code is licensed under the Microsoft Public License.
// See the file License.txt for the license details.
// More info on: http://dotnetzip.codeplex.com
//
// ------------------------------------------------------------------
//
// Last Saved: <2011-August-06 11:23:57>
//
// ------------------------------------------------------------------
//
// This module provides tests for password features.
//
// ------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.IO;
using Ionic.Zip;
using Ionic.Zip.Tests.Utilities;
namespace Ionic.Zip.Tests.Password
{
[TestClass]
public class PasswordTests : IonicTestClass
{
public PasswordTests() : base() { }
[TestMethod]
public void Password_BasicAddAndExtract()
{
int i;
string[] Passwords = { null, "Password!", TestUtilities.GenerateRandomPassword(), "A" };
Ionic.Zlib.CompressionLevel[] compressionLevelOptions = {
Ionic.Zlib.CompressionLevel.None,
Ionic.Zlib.CompressionLevel.BestSpeed,
Ionic.Zlib.CompressionLevel.Default,
Ionic.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");
}
}
}
[TestMethod]
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);
}
}
[TestMethod]
public void Password_UnsetEncryptionAfterSetPassword_wi13909_ZOS()
{
// Verify that unsetting the Encryption property after
// setting a Password results in no encryption being used.
// This method tests ZipOutputStream.
string unusedPassword = TestUtilities.GenerateRandomPassword();
int numTotalEntries = _rnd.Next(46)+653;
string zipFileToCreate = "UnsetEncryption.zip";
using (FileStream fs = File.Create(zipFileToCreate))
{
using (var zos = new ZipOutputStream(fs))
{
zos.Password = unusedPassword;
zos.Encryption = EncryptionAlgorithm.None;
for (int i=0; i < numTotalEntries; i++)
{
if (_rnd.Next(7)==0)
{
string entryName = String.Format("{0:D5}/", i);
zos.PutNextEntry(entryName);
}
else
{
string entryName = String.Format("{0:D5}.txt", i);
zos.PutNextEntry(entryName);
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);
zos.Write(buffer, 0, buffer.Length);
}
}
}
}
}
BasicVerifyZip(zipFileToCreate);
}
[TestMethod]
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);
}
[TestMethod]
[ExpectedException(typeof(Ionic.Zip.BadPasswordException))]
public void Password_CheckBadPassword_wi13668()
{
TestContext.WriteLine("Password_CheckBadPassword_wi13668()");
// In this case, the password is "correct" but the decrypted
// header does not match the CRC. Therefore the library
// should fail this password. I don't know how the zip was
// constructed but I suspect a broken library.
string fileName = _GetNameForZipContentFile("wi13668-bad-pwd-472713.zip");
string password = "472713";
TestContext.WriteLine("Reading zip file: '{0}'", fileName);
using (ZipFile zip = ZipFile.Read(fileName))
{
foreach (ZipEntry e in zip)
{
// will throw if wrong password
e.ExtractWithPassword(Stream.Null, password);
}
}
}
private string _GetNameForZipContentFile(string shortFileName)
{
string SourceDir = CurrentDir;
for (int i = 0; i < 3; i++)
SourceDir = Path.GetDirectoryName(SourceDir);
TestContext.WriteLine("Current Dir: {0}", CurrentDir);
return Path.Combine(SourceDir,
"Zip Tests\\bin\\Debug\\zips\\" + shortFileName);
}
[TestMethod]
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.");
}
}
}
[TestMethod]
[ExpectedException(typeof(Ionic.Zip.BadPasswordException))]
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");
}
}
[TestMethod]
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.");
}
}
[TestMethod]
public void SilentDeletion_wi10639()
{
string zipFileToCreate = "SilentDeletion.zip";
string dirToZip = "dirToZip";
string extractDir = "extracted";
string password = TestUtilities.GenerateRandomPassword();
string wrongPassword = "passworD";
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);
}
}
}
}