public static async Task Zip64ArchiveEntry_CorruptedFile_Read_UpToUncompressedSize() { MemoryStream stream = await LocalMemoryStream.readAppFileAsync(compat("deflate64.zip")); int nameOffset = PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 8); // patch uncompressed size in file header PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 22, nameOffset + s_tamperedFileName.Length); // patch in central directory too using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read)) { ZipArchiveEntry e = archive.GetEntry(s_tamperedFileName); using (var ms = new MemoryStream()) using (Stream source = e.Open()) { byte[] buffer = new byte[s_bufferSize]; int read; while ((read = source.Read(buffer, 0, buffer.Length)) != 0) { ms.Write(buffer, 0, read); } Assert.Equal(e.Length, ms.Length); // Only allow to decompress up to uncompressed size Assert.Equal(0, source.Read(buffer, 0, buffer.Length)); // Shouldn't be readable more } } }
public async Task CompressionLevel_SizeInOrder(string testFile) { using var uncompressedStream = await LocalMemoryStream.readAppFileAsync(testFile); async Task <long> GetLengthAsync(CompressionLevel compressionLevel) { using var mms = new MemoryStream(); using var compressor = CreateStream(mms, compressionLevel); await uncompressedStream.CopyToAsync(compressor); compressor.Flush(); return(mms.Length); } long noCompressionLength = await GetLengthAsync(CompressionLevel.NoCompression); long fastestLength = await GetLengthAsync(CompressionLevel.Fastest); long optimalLength = await GetLengthAsync(CompressionLevel.Optimal); long smallestLength = await GetLengthAsync(CompressionLevel.SmallestSize); Assert.True(noCompressionLength >= fastestLength); Assert.True(fastestLength >= optimalLength); Assert.True(optimalLength >= smallestLength); }
public async Task Decompress(CompressionType type) { string testFilePath = CreateCompressedFile(type); int _bufferSize = 1024; var bytes = new byte[_bufferSize]; using (MemoryStream gzStream = await LocalMemoryStream.readAppFileAsync(testFilePath)) using (MemoryStream strippedMs = StripHeaderAndFooter.Strip(gzStream)) foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) for (int i = 0; i < Benchmark.InnerIterationCount; i++) { int retCount = -1; using (DeflateStream zip = new DeflateStream(strippedMs, CompressionMode.Decompress, leaveOpen: true)) { while (retCount != 0) { retCount = zip.Read(bytes, 0, _bufferSize); } } strippedMs.Seek(0, SeekOrigin.Begin); } } File.Delete(testFilePath); }
public static async Task ZipArchiveEntry_CorruptedStream_ReadMode_Read_UpToUncompressedSize() { MemoryStream stream = await LocalMemoryStream.readAppFileAsync(zfile("normal.zip")); int nameOffset = PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 8); // patch uncompressed size in file header PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 22, nameOffset + s_tamperedFileName.Length); // patch in central directory too using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read)) { ZipArchiveEntry e = archive.GetEntry(s_tamperedFileName); using (MemoryStream ms = new MemoryStream()) using (Stream source = e.Open()) { byte[] buffer = new byte[s_bufferSize]; int read; while ((read = source.Read(buffer, 0, buffer.Length)) != 0) { ms.Write(buffer, 0, read); } Assert.Equal(e.Length, ms.Length); // Only allow to decompress up to uncompressed size Assert.Equal(0, source.Read(buffer, 0, s_bufferSize)); // shouldn't be able read more ms.Seek(0, SeekOrigin.Begin); while ((read = ms.Read(buffer, 0, buffer.Length)) != 0) { // No need to do anything, just making sure all bytes readable from output stream } Assert.Equal(ms.Position, ms.Length); // all bytes must be read } } }
public async Task OverlappingFlushAsync_DuringWriteAsync() { byte[] buffer = null; string testFilePath = gzTestFile("GZTestDocument.pdf"); using (var origStream = await LocalMemoryStream.readAppFileAsync(testFilePath)) { buffer = origStream.ToArray(); } using (var writeStream = new ManualSyncMemoryStream(false)) using (var zip = CreateStream(writeStream, CompressionMode.Compress)) { Task task = null; try { task = WriteAsync(zip, buffer, 0, buffer.Length); Assert.True(writeStream.WriteHit); Assert.Throws <InvalidOperationException>(() => { zip.FlushAsync(); }); // "overlapping flushes" } finally { // Unblock Async operations writeStream.manualResetEvent.Set(); // The original WriteAsync should be able to complete Assert.True(task.Wait(100 * 500)); } } }
public static async Task LargeArchive_DataDescriptor_Read_NonZip64_FileLengthGreaterThanIntMax() { MemoryStream stream = await LocalMemoryStream.readAppFileAsync(strange("fileLengthGreaterIntLessUInt.zip")); using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read)) { ZipArchiveEntry e = archive.GetEntry("large.bin"); Assert.Equal(3_600_000_000, e.Length); Assert.Equal(3_499_028, e.CompressedLength); using (Stream source = e.Open()) { byte[] buffer = new byte[s_bufferSize]; int read = source.Read(buffer, 0, buffer.Length); // We don't want to inflate this large archive entirely // just making sure it read successfully Assert.Equal(s_bufferSize, read); foreach (byte b in buffer) { if (b != '0') { Assert.True(false, $"The file should be all '0's, but found '{(char)b}'"); } } } } }
// Call this to create a new stream based on the bytes of the current one // It creates a temporary stream because it may already be disposed public LocalMemoryStream Clone() { var ms = new MemoryStream(this.ToArray()); var local = new LocalMemoryStream(); ms.CopyTo(local); return local; }
// Call this to create a new stream based on the bytes of the current one // It creates a temporary stream because it may already be disposed public LocalMemoryStream Clone() { var ms = new MemoryStream(this.ToArray()); var local = new LocalMemoryStream(); ms.CopyTo(local); return local; }
public static async Task Zip64ArchiveEntry_CorruptedStream_CopyTo_UpToUncompressedSize() { MemoryStream stream = await LocalMemoryStream.readAppFileAsync(compat("deflate64.zip")); int nameOffset = PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 8); // patch uncompressed size in file header PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 22, nameOffset + s_tamperedFileName.Length); // patch in central directory too using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read)) { ZipArchiveEntry e = archive.GetEntry(s_tamperedFileName); using (var ms = new MemoryStream()) using (Stream source = e.Open()) { source.CopyTo(ms); Assert.Equal(e.Length, ms.Length); // Only allow to decompress up to uncompressed size ms.Seek(0, SeekOrigin.Begin); int read; byte[] buffer = new byte[s_bufferSize]; while ((read = ms.Read(buffer, 0, buffer.Length)) != 0) { // No need to do anything, just making sure all bytes readable } Assert.Equal(ms.Position, ms.Length); // all bytes must be read } } }
public static async Task testFolder(String s) { var zs = new LocalMemoryStream(); await ZipTest.CreateFromDir(ZipTest.zfolder(s), zs, ZipArchiveMode.Update); ZipTest.IsZipSameAsDir(zs.Clone(), ZipTest.zfolder(s), ZipArchiveMode.Read, false, false); }
public static async Task UpdateCreate(string zipFolder) { var zs = new LocalMemoryStream(); await CreateFromDir(zfolder(zipFolder), zs, ZipArchiveMode.Update); IsZipSameAsDir(zs.Clone(), zfolder(zipFolder), ZipArchiveMode.Read, requireExplicit: true, checkTimes: true); }
public static async Task DecompressWorksWithBinaryFile() { var compareStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.doc")); var gzStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.doc.gz")); await DecompressAsync(compareStream, gzStream); }
public static async Task UpdateCreate(string zipFolder) { var zs = new LocalMemoryStream(); await CreateFromDir(zfolder(zipFolder), zs, ZipArchiveMode.Update); IsZipSameAsDir(zs.Clone(), zfolder(zipFolder), ZipArchiveMode.Read, false, false); }
public async Task DecompressWorksWithPdf() { var compareStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.pdf")); var gzStream = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.pdf.gz")); await DecompressAsync(compareStream, gzStream); }
public void Ctor_InvalidStream_Throws(CompressionMode mode) { LocalMemoryStream ms = new LocalMemoryStream(); ms.SetCanRead(mode == CompressionMode.Compress); ms.SetCanWrite(mode == CompressionMode.Decompress); AssertExtensions.Throws <ArgumentException>("stream", () => CreateStream(ms, mode)); }
public static async Task<LocalMemoryStream> readAppFileAsync(string testFile) { var baseStream = await StreamHelpers.CreateTempCopyStream(testFile); var ms = new LocalMemoryStream(); await baseStream.CopyToAsync(ms); ms.Position = 0; return ms; }
public static async Task<LocalMemoryStream> readAppFileAsync(String testFile) { var baseStream = await StreamHelpers.CreateTempCopyStream(testFile); var ms = new LocalMemoryStream(); await baseStream.CopyToAsync(ms); ms.Position = 0; return ms; }
public async Task ModifyBaseStream() { var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz")); var zip = new GZipStream(ms, CompressionMode.Decompress); int size = 1024; Byte[] bytes = new Byte[size]; zip.BaseStream.Read(bytes, 0, size); // This will throw if the underlying stream is not writeable as expected }
public static void EmptyEntryTest(ZipArchiveMode mode) { string data1 = "test data written to file."; string data2 = "more test data written to file."; DateTimeOffset lastWrite = new DateTimeOffset(1992, 4, 5, 12, 00, 30, new TimeSpan(-5, 0, 0)); var baseline = new LocalMemoryStream(); using (ZipArchive archive = new ZipArchive(baseline, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; using (Stream s = e.Open()) { } AddEntry(archive, "data2.txt", data2, lastWrite); } var test = new LocalMemoryStream(); using (ZipArchive archive = new ZipArchive(test, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; AddEntry(archive, "data2.txt", data2, lastWrite); } //compare Assert.True(ArraysEqual(baseline.ToArray(), test.ToArray()), "Arrays didn't match"); //second test, this time empty file at end baseline = baseline.Clone(); using (ZipArchive archive = new ZipArchive(baseline, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; using (Stream s = e.Open()) { } } test = test.Clone(); using (ZipArchive archive = new ZipArchive(test, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; } //compare Assert.True(ArraysEqual(baseline.ToArray(), test.ToArray()), "Arrays didn't match after update"); }
public void ReadOnlyStreamThrowsOnCompress() { var ms = new LocalMemoryStream(); ms.SetCanWrite(false); Assert.Throws <ArgumentException>(() => { var gzip = new DeflateStream(ms, CompressionMode.Compress); }); }
public void ReadOnlyStreamThrowsOnCompress() { var ms = new LocalMemoryStream(); ms.SetCanWrite(false); AssertExtensions.Throws <ArgumentException>("stream", () => { var gzip = new GZipStream(ms, CompressionMode.Compress); }); }
public void WriteOnlyStreamThrowsOnDecompress() { var ms = new LocalMemoryStream(); ms.SetCanRead(false); Assert.Throws <ArgumentException>(() => { var gzip = new GZipStream(ms, CompressionMode.Decompress); }); }
public static void EmptyEntryTest(ZipArchiveMode mode) { string data1 = "test data written to file."; string data2 = "more test data written to file."; DateTimeOffset lastWrite = new DateTimeOffset(1992, 4, 5, 12, 00, 30, new TimeSpan(-5, 0, 0)); var baseline = new LocalMemoryStream(); using (ZipArchive archive = new ZipArchive(baseline, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; using (Stream s = e.Open()) { } AddEntry(archive, "data2.txt", data2, lastWrite); } var test = new LocalMemoryStream(); using (ZipArchive archive = new ZipArchive(test, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; AddEntry(archive, "data2.txt", data2, lastWrite); } //compare Assert.True(ArraysEqual(baseline.ToArray(), test.ToArray()), "Arrays didn't match"); //second test, this time empty file at end baseline = baseline.Clone(); using (ZipArchive archive = new ZipArchive(baseline, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; using (Stream s = e.Open()) { } } test = test.Clone(); using (ZipArchive archive = new ZipArchive(test, mode)) { AddEntry(archive, "data1.txt", data1, lastWrite); ZipArchiveEntry e = archive.CreateEntry("empty.txt"); e.LastWriteTime = lastWrite; } //compare Assert.True(ArraysEqual(baseline.ToArray(), test.ToArray()), "Arrays didn't match after update"); }
public async Task DecompressFailsWithWrapperStream(string uncompressedPath, string newDirectory, string newSuffix) { string fileName = Path.Combine(newDirectory, Path.GetFileName(uncompressedPath) + newSuffix); using (LocalMemoryStream baseStream = await LocalMemoryStream.readAppFileAsync(fileName)) using (Stream cs = CreateStream(baseStream, CompressionMode.Decompress)) { int _bufferSize = 2048; var bytes = new byte[_bufferSize]; Assert.Throws <InvalidDataException>(() => { cs.Read(bytes, 0, _bufferSize); }); } }
public async Task DecompressFailsWithRealGzStream(string uncompressedPath) { string fileName = Path.Combine("GZipTestData", Path.GetFileName(uncompressedPath) + ".gz"); var baseStream = await LocalMemoryStream.readAppFileAsync(fileName); var zip = CreateStream(baseStream, CompressionMode.Decompress); int _bufferSize = 2048; var bytes = new byte[_bufferSize]; Assert.Throws <InvalidDataException>(() => { zip.Read(bytes, 0, _bufferSize); }); zip.Dispose(); }
public static async Task ZipArchive_CorruptedLocalHeader_CompressedSize_NotMatchWithCentralDirectory() { MemoryStream stream = await LocalMemoryStream.readAppFileAsync(zfile("normal.zip")); PatchDataRelativeToFileName(Encoding.ASCII.GetBytes(s_tamperedFileName), stream, 12); // patch compressed size in file header using (ZipArchive archive = new ZipArchive(stream, ZipArchiveMode.Read)) { ZipArchiveEntry e = archive.GetEntry(s_tamperedFileName); Assert.Throws <InvalidDataException>(() => e.Open()); } }
public async Task DecompressFailsWithRealGzStream() { string[] files = { gzTestFile("GZTestDocument.doc.gz"), gzTestFile("GZTestDocument.txt.gz") }; foreach (string fileName in files) { var baseStream = await LocalMemoryStream.readAppFileAsync(fileName); var zip = new DeflateStream(baseStream, CompressionMode.Decompress); int _bufferSize = 2048; var bytes = new byte[_bufferSize]; Assert.Throws <InvalidDataException>(() => { zip.Read(bytes, 0, _bufferSize); }); zip.Dispose(); } }
public async Task CanReadBaseStreamAfterDispose() { var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz")); var zip = new GZipStream(ms, CompressionMode.Decompress, leaveOpen: true); var baseStream = zip.BaseStream; zip.Dispose(); int size = 1024; byte[] bytes = new byte[size]; baseStream.Read(bytes, 0, size); // This will throw if the underlying stream is not writable as expected }
public async Task ModifyBaseStream() { var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz")); var newMs = StripHeaderAndFooter.Strip(ms); var zip = new DeflateStream(newMs, CompressionMode.Decompress); int size = 1024; byte[] bytes = new byte[size]; zip.BaseStream.Read(bytes, 0, size); // This will throw if the underlying stream is not writable as expected zip.BaseStream.Position = 0; await zip.BaseStream.ReadAsync(bytes, 0, size); }
public static void InvalidConstructors() { //out of range enum values ConstructorThrows <ArgumentOutOfRangeException>(() => new ZipArchive(new MemoryStream(), (ZipArchiveMode)(-1)), "Out of range enum"); ConstructorThrows <ArgumentOutOfRangeException>(() => new ZipArchive(new MemoryStream(), (ZipArchiveMode)(4)), "out of range enum"); ConstructorThrows <ArgumentOutOfRangeException>(() => new ZipArchive(new MemoryStream(), (ZipArchiveMode)(10)), "Out of range enum"); //null/closed stream ConstructorThrows <ArgumentNullException>(() => new ZipArchive((Stream)null, ZipArchiveMode.Read), "Null/closed stream"); ConstructorThrows <ArgumentNullException>(() => new ZipArchive((Stream)null, ZipArchiveMode.Create), "Null/closed stream"); ConstructorThrows <ArgumentNullException>(() => new ZipArchive((Stream)null, ZipArchiveMode.Update), "Null/closed stream"); MemoryStream ms = new MemoryStream(); ms.Dispose(); ConstructorThrows <ArgumentException>(() => new ZipArchive(ms, ZipArchiveMode.Read), "Disposed Base Stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(ms, ZipArchiveMode.Create), "Disposed Base Stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(ms, ZipArchiveMode.Update), "Disposed Base Stream"); //non-seekable to update using (LocalMemoryStream nonReadable = new LocalMemoryStream(), nonWriteable = new LocalMemoryStream(), nonSeekable = new LocalMemoryStream()) { nonReadable.SetCanRead(false); nonWriteable.SetCanWrite(false); nonSeekable.SetCanSeek(false); ConstructorThrows <ArgumentException>(() => new ZipArchive(nonReadable, ZipArchiveMode.Read), "Non readable stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(nonWriteable, ZipArchiveMode.Create), "Non-writable stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(nonReadable, ZipArchiveMode.Update), "Non-readable stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(nonWriteable, ZipArchiveMode.Update), "Non-writable stream"); ConstructorThrows <ArgumentException>(() => new ZipArchive(nonSeekable, ZipArchiveMode.Update), "Non-seekable stream"); } }
public async Task BaseStream_Modify(CompressionMode mode) { using (var baseStream = await LocalMemoryStream.readAppFileAsync(CompressedTestFile(UncompressedTestFile()))) using (var compressor = CreateStream(baseStream, mode)) { int size = 1024; byte[] bytes = new byte[size]; if (mode == CompressionMode.Compress) { BaseStream(compressor).Write(bytes, 0, size); // This will throw if the underlying stream is not writable as expected } else { BaseStream(compressor).Read(bytes, 0, size); // This will throw if the underlying stream is not readable as expected } } }
public async Task TestLeaveOpenAfterValidDecompress() { //Create the Stream int _bufferSize = 1024; var bytes = new byte[_bufferSize]; Stream compressedStream = await LocalMemoryStream.readAppFileAsync(CompressedTestFile(UncompressedTestFile())); Stream decompressor = CreateStream(compressedStream, CompressionMode.Decompress, leaveOpen: false); //Read some data and Close the stream decompressor.Read(bytes, 0, _bufferSize); decompressor.Flush(); decompressor.Dispose(); //Check that Close has really closed the underlying stream Assert.Throws <ObjectDisposedException>(() => compressedStream.Read(bytes, 0, bytes.Length)); }
public async Task CanReadBaseStreamAfterDispose() { var ms = await LocalMemoryStream.readAppFileAsync(gzTestFile("GZTestDocument.txt.gz")); var newMs = StripHeaderAndFooter.Strip(ms); var zip = new DeflateStream(newMs, CompressionMode.Decompress, true); var baseStream = zip.BaseStream; zip.Dispose(); int size = 1024; Byte[] bytes = new Byte[size]; baseStream.Read(bytes, 0, size); // This will throw if the underlying stream is not writeable as expected baseStream.Position = 0; await baseStream.ReadAsync(bytes, 0, size); }
public void WriteOnlyStreamThrowsOnDecompress() { var ms = new LocalMemoryStream(); ms.SetCanRead(false); Assert.Throws<ArgumentException>(() => { var gzip = new DeflateStream(ms, CompressionMode.Decompress); }); }
public void ReadOnlyStreamThrowsOnCompress() { var ms = new LocalMemoryStream(); ms.SetCanWrite(false); Assert.Throws<ArgumentException>(() => { var gzip = new GZipStream(ms, CompressionMode.Compress); }); }
public static async Task UpdateCreate(string zipFolder) { var zs = new LocalMemoryStream(); await ZipTest.CreateFromDir(ZipTest.zfolder(zipFolder), zs, ZipArchiveMode.Update); ZipTest.IsZipSameAsDir(zs.Clone(), ZipTest.zfolder(zipFolder), ZipArchiveMode.Read, false, false); }
public static async Task UpdateCreate(string zipFolder) { var zs = new LocalMemoryStream(); await CreateFromDir(zfolder(zipFolder), zs, ZipArchiveMode.Update); IsZipSameAsDir(zs.Clone(), zfolder(zipFolder), ZipArchiveMode.Read, requireExplicit: true, checkTimes: true); }