public async Task CanReadFromAChangedStream() { // Arrange using (var streamA = TestUtility.BufferTestData(@"System.IO.Compression\refzipfiles\normal.zip")) using (var streamB = TestUtility.BufferTestData(@"System.IO.Compression\refzipfiles\small.zip")) using (var sourceStream = new MemoryStream()) { var expected = (await TestUtility.ReadWithMiniZipAsync(streamB)).Data; await streamA.CopyToAsync(sourceStream); var reader = new ZipDirectoryReader(sourceStream); await reader.ReadAsync(); sourceStream.SetLength(0); streamB.Position = 0; await streamB.CopyToAsync(sourceStream); // Act var actual = await reader.ReadAsync(); // Assert Assert.NotSame(expected, actual); TestUtility.VerifyJsonEquals(expected, actual); } }
public async Task AllowsReadingOfZipCentralDirectory(string path) { // Arrange var originalStream = TestUtility.BufferTestData(path); var result = await TestUtility.ReadWithMiniZipAsync(originalStream); var expected = result.Data; var innerStream = new MemoryStream(); var prefix = new byte[2345]; var suffix = new byte[6789]; innerStream.Write(prefix, 0, prefix.Length); originalStream.Position = 0; await originalStream.CopyToAsync(innerStream); innerStream.Write(suffix, 0, suffix.Length); var target = new BoundedStream(innerStream, prefix.Length, (prefix.Length + originalStream.Length) - 1); var reader = new ZipDirectoryReader(target); var expectedSize = originalStream.Length; // Act var actual = await reader.ReadAsync(); // Assert TestUtility.VerifyJsonEquals(expected, actual); Assert.Equal(expectedSize, target.Length); Assert.Equal(prefix.Length + target.Length + suffix.Length, innerStream.Length); }
public async Task AllowsReadingOfZipCentralDirectory(string path) { // Arrange var originalStream = TestUtility.BufferTestData(path); var result = await TestUtility.ReadWithMiniZipAsync(originalStream); var expected = result.Data; var innerStream = new MemoryStream(); var virtualOffset = (long)(expected.Zip64?.OffsetOfCentralDirectory ?? expected.OffsetOfCentralDirectory); originalStream.Position = virtualOffset; await originalStream.CopyToAsync(innerStream); var target = new VirtualOffsetStream(innerStream, virtualOffset); var reader = new ZipDirectoryReader(target); var expectedSize = originalStream.Length - virtualOffset; // Act var actual = await reader.ReadAsync(); // Assert TestUtility.VerifyJsonEquals(expected, actual); Assert.Equal(expectedSize, innerStream.Length); Assert.Equal(originalStream.Length, target.Length); }
public static async Task <MiniZipResult> ReadWithMiniZipAsync(Stream stream) { stream.Position = 0; try { using (var reader = new ZipDirectoryReader(stream, leaveOpen: true)) { var data = await reader.ReadAsync(); return(new MiniZipResult { Success = true, Data = data, }); } } catch (Exception e) { return(new MiniZipResult { Success = false, Exception = e, }); } }
/// <summary> /// Initialize the ZIP directory reader for the provided request URL. /// </summary> /// <param name="requestUri">The request URL.</param> /// <returns>The ZIP directory reader.</returns> public async Task <ZipDirectoryReader> GetReaderAsync(Uri requestUri) { var stream = await GetStreamAsync(requestUri); var reader = new ZipDirectoryReader(stream); return(reader); }
public async Task ReadsDirectoryComment() { // Arrange using (var stream = TestUtility.BufferTestData("Custom/comment-on-archive.zip")) { var reader = new ZipDirectoryReader(stream); // Act var output = await reader.ReadAsync(); // Assert Assert.Equal("This is a comment on the entire archive.", output.GetComment()); } }
public async Task CanGatherAndRecreateNuGetPackageCentralDirectory() { using (var testDirectory = TestDirectory.Create()) { // Discover the .nupkg URL. var sourceRepository = Repository.Factory.GetCoreV3("https://api.nuget.org/v3/index.json"); var serviceIndex = await sourceRepository.GetResourceAsync <ServiceIndexResourceV3>(); var packageBaseAddress = serviceIndex.GetServiceEntryUri(ServiceTypes.PackageBaseAddress); var id = "Newtonsoft.Json".ToLowerInvariant(); var version = NuGetVersion.Parse("9.0.1").ToNormalizedString().ToLowerInvariant(); var packageUri = new Uri(packageBaseAddress, $"{id}/{version}/{id}.{version}.nupkg"); ZipDirectory zipDirectoryA; string mzipPath; using (var httpClient = new HttpClient()) { var httpZipProvider = new HttpZipProvider(httpClient); using (var reader = await httpZipProvider.GetReaderAsync(packageUri)) { // Read the ZIP directory from the .nupkg URL. zipDirectoryA = await reader.ReadAsync(); // Save the .mzip to the test directory. mzipPath = Path.Combine(testDirectory, $"{id}.{version}.mzip"); using (var fileStream = new FileStream(mzipPath, FileMode.Create)) { var mzipFormat = new MZipFormat(); await mzipFormat.WriteAsync(reader.Stream, fileStream); } } } // Read the .mzip back from disk. ZipDirectory zipDirectoryB; using (var fileStream = new FileStream(mzipPath, FileMode.Open)) { var mzipFormat = new MZipFormat(); using (var mzipStream = await mzipFormat.ReadAsync(fileStream)) using (var reader = new ZipDirectoryReader(mzipStream)) { zipDirectoryB = await reader.ReadAsync(); } } // Compare the results. TestUtility.VerifyJsonEquals(zipDirectoryA, zipDirectoryB); } }
public async Task RejectsOffsetOutOfBounds() { // Assert using (var stream = TestUtility.BufferTestData(@"System.IO.Compression\badzipfiles\localFileOffsetOutOfBounds.zip")) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); var entry = directory.Entries[0]; // Act & Assert await Assert.ThrowsAsync <EndOfStreamException>( () => reader.ReadLocalFileHeaderAsync(directory, entry)); } }
public async Task ReadsEntryComment() { // Arrange using (var stream = TestUtility.BufferTestData("Custom/comment-on-entry.zip")) { var reader = new ZipDirectoryReader(stream); // Act var output = await reader.ReadAsync(); // Assert Assert.Equal(2, output.Entries.Count); Assert.Empty(output.Entries.Single(x => x.GetName() == "no-comment.txt").GetComment()); Assert.Equal("Comment on test.txt", output.Entries.Single(x => x.GetName() == "test.txt").GetComment()); } }
public async Task AllowsReadingTwice() { // Arrange using (var stream = TestUtility.BufferTestData(@"System.IO.Compression\refzipfiles\normal.zip")) { var reader = new ZipDirectoryReader(stream); // Act var outputA = await reader.ReadAsync(); var outputB = await reader.ReadAsync(); // Assert Assert.NotSame(outputA, outputB); TestUtility.VerifyJsonEquals(outputA, outputB); } }
public async Task ReadsUncompressedFile() { // Arrange using (var stream = TestUtility.BufferTestData("Custom/basetestpackage.1.0.0.nupkg")) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); var entry = directory.Entries.Single(x => x.GetName() == ".signature.p7s"); // Act var data = await reader.ReadUncompressedFileDataAsync(directory, entry); // Assert Assert.Equal(TestUtility.ReadTestData("Custom/.signature.p7s"), data); } }
public async Task RejectsEncryptedFiles() { // Arrange using (var stream = TestUtility.BufferTestData(@"SharpZipLib\FastZipHandling.Encryption\0.zip")) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); var entry = directory.Entries[0]; // Act & Assert var ex = await Assert.ThrowsAsync <MiniZipException>( () => reader.ReadLocalFileHeaderAsync(directory, entry)); Assert.Equal("Archives containing encrypted files are not supported.", ex.Message); } }
public async Task RejectsInvalidLocalFileHeaderSignature() { // Assert using (var stream = TestUtility.BufferTestData(@"System.IO.Compression\badzipfiles\localFileHeaderSignatureWrong.zip")) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); var entry = directory.Entries[0]; // Act & Assert var ex = await Assert.ThrowsAsync <MiniZipException>( () => reader.ReadLocalFileHeaderAsync(directory, entry)); Assert.Equal("Invalid local file header signature found.", ex.Message); } }
public async Task CanGatherAndRecreateNuGetPackageCentralDirectory(string id, string version) { using (var testDirectory = TestDirectory.Create()) { var packageUri = await NuGetUtility.GetNupkgUrlAsync(id, version); ZipDirectory zipDirectoryA; string mzipPath; using (var httpClient = new HttpClient()) { var httpZipProvider = new HttpZipProvider(httpClient) { RequireAcceptRanges = false, }; using (var reader = await httpZipProvider.GetReaderAsync(packageUri)) { // Read the ZIP directory from the .nupkg URL. zipDirectoryA = await reader.ReadAsync(); // Save the .mzip to the test directory. mzipPath = Path.Combine(testDirectory, $"{id}.{version}.mzip"); using (var fileStream = new FileStream(mzipPath, FileMode.Create)) { var mzipFormat = new MZipFormat(); await mzipFormat.WriteAsync(reader.Stream, fileStream); } } } // Read the .mzip back from disk. ZipDirectory zipDirectoryB; using (var fileStream = new FileStream(mzipPath, FileMode.Open)) { var mzipFormat = new MZipFormat(); using (var mzipStream = await mzipFormat.ReadAsync(fileStream)) using (var reader = new ZipDirectoryReader(mzipStream)) { zipDirectoryB = await reader.ReadAsync(); } } // Compare the results. TestUtility.VerifyJsonEquals(zipDirectoryA, zipDirectoryB); } }
/// <summary> /// Writes the central directory of the ZIP file in the <paramref name="srcStream"/> to the /// <paramref name="dstStream"/>. The <paramref name="dstStream"/> should be read using /// <see cref="ReadAsync(Stream)"/>. /// </summary> /// <param name="srcStream">The stream to be read which contains a ZIP file.</param> /// <param name="dstStream">The stream to be written to which will contain the central directory.</param> public async Task WriteAsync(Stream srcStream, Stream dstStream) { using (var reader = new ZipDirectoryReader(srcStream, leaveOpen: true)) { var zipDirectory = await reader.ReadAsync(); // First, write the offset of the central directory. var position = (long)(zipDirectory.Zip64?.OffsetOfCentralDirectory ?? zipDirectory.OffsetOfCentralDirectory); using (var binaryWriter = new BinaryWriter(dstStream, Encoding.ASCII, leaveOpen: true)) { binaryWriter.Write((ulong)position); } // Next, write the central directory itself. srcStream.Position = position; await srcStream.CopyToAsync(dstStream); } }
public async Task ReadsLocalHeaderOfAllFiles(string resourceName) { // Arrange using (var stream = TestUtility.BufferTestData(resourceName)) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); // Act foreach (var entry in directory.Entries) { var localFileHeader = await reader.ReadLocalFileHeaderAsync(directory, entry); // Assert Assert.NotNull(localFileHeader); } } }
public async Task ReadsDataDescriptorWithoutSignature(string resourceName) { // Arrange using (var stream = TestUtility.BufferTestData(resourceName)) { var reader = new ZipDirectoryReader(stream); var directory = await reader.ReadAsync(); var entry = directory.Entries[0]; // Act var localFileHeader = await reader.ReadLocalFileHeaderAsync(directory, entry); // Assert Assert.NotNull(localFileHeader.DataDescriptor); Assert.False(localFileHeader.DataDescriptor.HasSignature); Assert.Equal(entry.Crc32, localFileHeader.DataDescriptor.Crc32); Assert.Equal(entry.CompressedSize, localFileHeader.DataDescriptor.CompressedSize); Assert.Equal(entry.UncompressedSize, localFileHeader.DataDescriptor.UncompressedSize); } }
public async Task Run() { var name1 = "CloudBlockBlob and ZipArchive"; var average1 = await ExecuteTestsAsync( name1, async (url) => { var blobClient = new CloudBlobClient( new Uri("https://example"), new FixUpBlobStorageHandler { InnerHandler = new HttpClientDelegatingHandler(_client), }); blobClient.DefaultRequestOptions.DisableContentMD5Validation = true; var blob = new CloudBlockBlob(url, blobClient); using (var stream = await blob.OpenReadAsync()) using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Read)) { var entries = zipArchive.Entries.ToList(); } }); var name2 = "CloudBlockBlob and ZipDirectoryReader"; var average2 = await ExecuteTestsAsync( name2, async (url) => { var blobClient = new CloudBlobClient( new Uri("https://example"), new FixUpBlobStorageHandler { InnerHandler = new HttpClientDelegatingHandler(_client), }); blobClient.DefaultRequestOptions.DisableContentMD5Validation = true; var blob = new CloudBlockBlob(url, blobClient); using (var stream = await blob.OpenReadAsync()) using (var zipDirectoryReader = new ZipDirectoryReader(stream)) { var zipDirectory = await zipDirectoryReader.ReadAsync(); } }); var name3 = "HttpZipProvider"; var average3 = await ExecuteTestsAsync( name3, async (url) => { // Read the entries using HttpClient and MiniZip. var httpZipProvider = new HttpZipProvider(_client); using (var reader = await httpZipProvider.GetReaderAsync(url)) { var zipDirectory = await reader.ReadAsync(); } }); Assert.True(average2 < average1, $"'{name2}' should be less than '{name1}'."); Assert.True(average3 < average1, $"'{name3}' should be less than '{name1}'."); // This is what we want. Ideally the stream provided by HttpZipProvider performs better than CloudBlockBlob. Assert.True(average2 < average3, $"'{name2}' should be less than '{name3}'."); }