public void StreamCorruption_IsDetected() { byte[] source = Enumerable.Range(0, 64).Select(i => (byte)i).ToArray(); var buffer = new byte[64]; byte[] compressedData; using (var compressed = new MemoryStream()) using (Stream compressor = CreateStream(compressed, CompressionMode.Compress)) { foreach (byte b in source) { compressor.WriteByte(b); } compressor.Dispose(); compressedData = compressed.ToArray(); } // the last 7 bytes of the 10-byte gzip header can be changed with no decompression error // this is by design, so we skip them for the test int[] byteToSkip = { 3, 4, 5, 6, 7, 8, 9 }; for (int byteToCorrupt = 0; byteToCorrupt < compressedData.Length; byteToCorrupt++) { if (byteToSkip.Contains(byteToCorrupt)) { continue; } // corrupt the data compressedData[byteToCorrupt]++; using (var decompressedStream = new MemoryStream(compressedData)) { using (Stream decompressor = CreateStream(decompressedStream, CompressionMode.Decompress)) { Assert.Throws <InvalidDataException>(() => { while (ZipFileTestBase.ReadAllBytes(decompressor, buffer, 0, buffer.Length) != 0) { ; } }); } } // restore the data compressedData[byteToCorrupt]--; } }
public void StreamCorruption_IsDetected() { byte[] source = Enumerable.Range(0, 64).Select(i => (byte)i).ToArray(); var buffer = new byte[64]; byte[] compressedData; using (var compressed = new MemoryStream()) using (Stream compressor = CreateStream(compressed, CompressionMode.Compress)) { foreach (byte b in source) { compressor.WriteByte(b); } compressor.Dispose(); compressedData = compressed.ToArray(); } for (int byteToCorrupt = 0; byteToCorrupt < compressedData.Length; byteToCorrupt++) { // corrupt the data compressedData[byteToCorrupt]++; using (var decompressedStream = new MemoryStream(compressedData)) { using (Stream decompressor = CreateStream(decompressedStream, CompressionMode.Decompress)) { Assert.Throws <InvalidDataException>(() => { while (ZipFileTestBase.ReadAllBytes(decompressor, buffer, 0, buffer.Length) != 0) { ; } }); } } // restore the data compressedData[byteToCorrupt]--; } }
public async Task StreamTruncation_IsDetected(TestScenario scenario) { var buffer = new byte[16]; byte[] source = Enumerable.Range(0, 64).Select(i => (byte)i).ToArray(); byte[] compressedData; using (var compressed = new MemoryStream()) using (Stream compressor = CreateStream(compressed, CompressionMode.Compress)) { foreach (byte b in source) { compressor.WriteByte(b); } compressor.Dispose(); compressedData = compressed.ToArray(); } for (var i = 1; i <= compressedData.Length; i += 1) { bool expectException = i < compressedData.Length; using (var compressedStream = new MemoryStream(compressedData.Take(i).ToArray())) { using (Stream decompressor = CreateStream(compressedStream, CompressionMode.Decompress)) { var decompressedStream = new MemoryStream(); try { switch (scenario) { case TestScenario.Copy: decompressor.CopyTo(decompressedStream); break; case TestScenario.CopyAsync: await decompressor.CopyToAsync(decompressedStream); break; case TestScenario.Read: while (ZipFileTestBase.ReadAllBytes(decompressor, buffer, 0, buffer.Length) != 0) { } ; break; case TestScenario.ReadAsync: while (await ZipFileTestBase.ReadAllBytesAsync(decompressor, buffer, 0, buffer.Length) != 0) { } ; break; case TestScenario.ReadByte: while (decompressor.ReadByte() != -1) { } break; case TestScenario.ReadByteAsync: while (await decompressor.ReadByteAsync() != -1) { } break; } } catch (InvalidDataException e) { if (expectException) { continue; } throw new XunitException($"An unexpected error occurred while decompressing data:{e}"); } if (expectException) { throw new XunitException($"Truncated stream was decompressed successfully but exception was expected: length={i}/{compressedData.Length}"); } } } } }