Exemple #1
0
            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);
            }
Exemple #4
0
        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);
        }
Exemple #6
0
            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());
                }
            }
Exemple #7
0
        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);
            }
        }
Exemple #8
0
            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));
                }
            }
Exemple #9
0
            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());
                }
            }
Exemple #10
0
            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);
                }
            }
Exemple #11
0
            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);
                }
            }
Exemple #12
0
            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);
                }
            }
Exemple #13
0
            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);
                }
            }
Exemple #14
0
        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);
            }
        }
Exemple #15
0
        /// <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);
            }
        }
Exemple #16
0
            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);
                    }
                }
            }
Exemple #17
0
            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}'.");
        }