Merge remote-tracking branch 'origin/master' into adam/write-async

# Conflicts:
#	src/SharpCompress/Compressors/LZMA/Lzma2EncoderStream.cs
#	src/SharpCompress/Factories/TarFactory.cs
#	src/SharpCompress/Polyfills/StreamExtensions.cs
#	src/SharpCompress/Writers/IWriter.cs
This commit is contained in:
Adam Hathcock
2026-05-14 16:12:13 +01:00
134 changed files with 4378 additions and 4543 deletions

View File

@@ -73,7 +73,7 @@ public class AceReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(testArchive);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions()
ReaderOptions.ForExternalStream
);
while (await reader.MoveToNextEntryAsync())
{
@@ -95,7 +95,10 @@ public class AceReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(testArchive);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (await reader.MoveToNextEntryAsync())
{

View File

@@ -0,0 +1,723 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using SharpCompress.Archives;
using SharpCompress.Common;
using SharpCompress.Factories;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using Xunit;
namespace SharpCompress.Test;
public class ArchiveFactoryTests : TestBase
{
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
[InlineData("Rar.rar", typeof(RarFactory))]
[InlineData("7Zip.nonsolid.7z", typeof(SevenZipFactory))]
public async ValueTask FindFactoryAsync_String_ReturnsExpectedFactory(
string archiveName,
System.Type expectedFactoryType
)
{
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.IsType(expectedFactoryType, factory);
}
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
[InlineData("Rar.rar", typeof(RarFactory))]
[InlineData("7Zip.nonsolid.7z", typeof(SevenZipFactory))]
public async ValueTask FindFactoryAsync_FileInfo_ReturnsExpectedFactory(
string archiveName,
System.Type expectedFactoryType
)
{
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(
new FileInfo(Path.Combine(TEST_ARCHIVES_PATH, archiveName))
);
Assert.IsType(expectedFactoryType, factory);
}
[Theory]
[InlineData("Zip.deflate.zip", typeof(ZipFactory))]
[InlineData("Tar.noEmptyDirs.tar", typeof(TarFactory))]
public async ValueTask FindFactoryAsync_Stream_PreservesPosition(
string archiveName,
System.Type expectedFactoryType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 7);
var startPosition = stream.Position;
var factory = await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(stream);
Assert.IsType(expectedFactoryType, factory);
Assert.Equal(startPosition, stream.Position);
}
[Fact]
public void OpenArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() => ArchiveFactory.OpenArchive([nonSeekable, seekable]));
}
[Fact]
public async ValueTask OpenAsyncArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
await Assert.ThrowsAsync<ArgumentException>(() =>
ArchiveFactory.OpenAsyncArchive([nonSeekable, seekable]).AsTask()
);
}
[Fact]
public async ValueTask FindFactoryAsync_InvalidData_ThrowsArchiveOperationException()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
await Assert.ThrowsAsync<ArchiveOperationException>(async () =>
await ArchiveFactory.FindFactoryAsync<IArchiveFactory>(stream)
);
}
[Fact]
public void OpenArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => ArchiveFactory.OpenArchive(unreadable));
}
[Fact]
public async ValueTask OpenAsyncArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
await Assert.ThrowsAsync<ArgumentException>(() =>
ArchiveFactory.OpenAsyncArchive(unreadable).AsTask()
);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
[InlineData("Rar.rar", ArchiveType.Rar)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip)]
public void IsArchive_String_ReturnsExpectedType(string archiveName, ArchiveType expectedType)
{
var result = ArchiveFactory.IsArchive(
Path.Combine(TEST_ARCHIVES_PATH, archiveName),
out var type
);
Assert.True(result);
Assert.Equal(expectedType, type);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
public void IsArchive_Stream_PreservesPosition(string archiveName, ArchiveType expectedType)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 11);
var startPosition = stream.Position;
var result = ArchiveFactory.IsArchive(stream, out var type);
Assert.True(result);
Assert.Equal(expectedType, type);
Assert.Equal(startPosition, stream.Position);
}
[Theory]
[InlineData("7Zip.LZMA2.exe", ArchiveType.SevenZip)]
[InlineData("Rar.jpeg.jpg", ArchiveType.Rar)]
public void IsArchive_WithReaderOptions_ReturnsExpectedType(
string archiveName,
ArchiveType expectedType
)
{
var result = ArchiveFactory.IsArchive(
GetTestArchivePath(archiveName),
ReaderOptions.ForFilePath.WithLookForHeader(true),
out var type
);
Assert.True(result);
Assert.Equal(expectedType, type);
}
[Theory]
[InlineData("7Zip.LZMA2.exe", ArchiveType.SevenZip)]
[InlineData("Rar.jpeg.jpg", ArchiveType.Rar)]
public async ValueTask IsArchiveAsync_WithReaderOptions_ReturnsExpectedType(
string archiveName,
ArchiveType expectedType
)
{
var result = await ArchiveFactory.IsArchiveAsync(
GetTestArchivePath(archiveName),
ReaderOptions.ForFilePath.WithLookForHeader(true)
);
Assert.True(result.IsArchive);
Assert.Equal(expectedType, result.Type);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
[InlineData("Rar.rar", ArchiveType.Rar)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip)]
public async ValueTask IsArchiveAsync_String_ReturnsExpectedType(
string archiveName,
ArchiveType expectedType
)
{
var result = await ArchiveFactory.IsArchiveAsync(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.True(result.IsArchive);
Assert.Equal(expectedType, result.Type);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
public async ValueTask IsArchiveAsync_Stream_PreservesPosition(
string archiveName,
ArchiveType expectedType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 11);
var startPosition = stream.Position;
var result = await ArchiveFactory.IsArchiveAsync(stream);
Assert.True(result.IsArchive);
Assert.Equal(expectedType, result.Type);
Assert.Equal(startPosition, stream.Position);
}
[Fact]
public async ValueTask IsArchiveAsync_InvalidData_ReturnsFalseAndNullType()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
var result = await ArchiveFactory.IsArchiveAsync(stream);
Assert.False(result.IsArchive);
Assert.Null(result.Type);
Assert.Equal(0, stream.Position);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip, true)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar, true)]
[InlineData("Rar.rar", ArchiveType.Rar, true)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip, true)]
[InlineData("Ace.store.ace", ArchiveType.Ace, false)]
[InlineData("Arc.uncompressed.arc", ArchiveType.Arc, false)]
public void GetArchiveInformation_ReturnsExpectedInfo(
string archiveName,
ArchiveType expectedType,
bool expectedRandomAccess
)
{
var info = ArchiveFactory.GetArchiveInformation(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedRandomAccess, info.SupportsRandomAccess);
}
[Theory]
[InlineData("7Zip.LZMA2.exe", ArchiveType.SevenZip, true)]
[InlineData("Rar.jpeg.jpg", ArchiveType.Rar, true)]
public void GetArchiveInformation_WithReaderOptions_ReturnsExpectedInfo(
string archiveName,
ArchiveType expectedType,
bool expectedRandomAccess
)
{
var info = ArchiveFactory.GetArchiveInformation(
GetTestArchivePath(archiveName),
ReaderOptions.ForFilePath.WithLookForHeader(true)
);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedRandomAccess, info.SupportsRandomAccess);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip, true)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar, true)]
[InlineData("Rar.rar", ArchiveType.Rar, true)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip, true)]
[InlineData("Ace.store.ace", ArchiveType.Ace, false)]
[InlineData("Arc.uncompressed.arc", ArchiveType.Arc, false)]
public async ValueTask GetArchiveInformationAsync_ReturnsExpectedInfo(
string archiveName,
ArchiveType expectedType,
bool expectedRandomAccess
)
{
var info = await ArchiveFactory.GetArchiveInformationAsync(
Path.Combine(TEST_ARCHIVES_PATH, archiveName)
);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedRandomAccess, info.SupportsRandomAccess);
}
[Theory]
[InlineData("7Zip.LZMA2.exe", ArchiveType.SevenZip, true)]
[InlineData("Rar.jpeg.jpg", ArchiveType.Rar, true)]
public async ValueTask GetArchiveInformationAsync_WithReaderOptions_ReturnsExpectedInfo(
string archiveName,
ArchiveType expectedType,
bool expectedRandomAccess
)
{
var info = await ArchiveFactory.GetArchiveInformationAsync(
GetTestArchivePath(archiveName),
ReaderOptions.ForFilePath.WithLookForHeader(true)
);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedRandomAccess, info.SupportsRandomAccess);
}
[Theory]
[InlineData("64bitstream.zip.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARM.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARM64.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARMT.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BCJ.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BCJ2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BZip2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Copy.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.EmptyStream.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Filters.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.IA64.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA.Aes.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA2.Aes.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.PPC.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.PPMd.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.RISCV.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.SPARC.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Tar.tar", ArchiveType.Tar, true)]
[InlineData("7Zip.Tar.tar.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ZSTD.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.delta.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.delta.distance.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.encryptedFiles.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.eos.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.solid.1block.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.solid.7z", ArchiveType.SevenZip, true)]
[InlineData("Ace.encrypted.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method1-solid.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method1.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method2-solid.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method2.ace", ArchiveType.Ace, false)]
[InlineData("Ace.store.ace", ArchiveType.Ace, false)]
[InlineData("Ace.store.largefile.ace", ArchiveType.Ace, false)]
[InlineData("Arc.crunched.arc", ArchiveType.Arc, false)]
[InlineData("Arc.crunched.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squashed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squashed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squeezed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squeezed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.uncompressed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.uncompressed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arj.encrypted.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method1.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method1.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method2.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method2.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method3.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method3.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method4.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method4.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.store.arj", ArchiveType.Arj, false)]
[InlineData("Arj.store.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Issue_685.zip", ArchiveType.Zip, true)]
[InlineData("PrePostHeaders.zip", ArchiveType.Zip, true)]
[InlineData("Rar.Audio_program.rar", ArchiveType.Rar, true)]
[InlineData("Rar.Encrypted.rar", ArchiveType.Rar, true)]
[InlineData("Rar.comment.rar", ArchiveType.Rar, true)]
[InlineData("Rar.encrypted_filesAndHeader.rar", ArchiveType.Rar, true)]
[InlineData("Rar.encrypted_filesOnly.rar", ArchiveType.Rar, true)]
[InlineData("Rar.issue1050.rar", ArchiveType.Rar, true)]
[InlineData("Rar.malformed_512byte.rar", ArchiveType.Rar, true)]
[InlineData("Rar.none.rar", ArchiveType.Rar, true)]
[InlineData("Rar.rar", ArchiveType.Rar, true)]
[InlineData("Rar.solid.rar", ArchiveType.Rar, true)]
[InlineData("Rar.test_invalid_exttime.rar", ArchiveType.Rar, true)]
[InlineData("Rar15.rar", ArchiveType.Rar, true)]
[InlineData("Rar2.rar", ArchiveType.Rar, true)]
[InlineData("Rar4.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.comment.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.crc_blake2.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.encrypted_filesAndHeader.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.encrypted_filesOnly.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.none.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.solid.rar", ArchiveType.Rar, true)]
[InlineData("Tar.ContainsRar.tar", ArchiveType.Tar, true)]
[InlineData("Tar.ContainsTarGz.tar", ArchiveType.Tar, true)]
[InlineData("Tar.Empty.tar", ArchiveType.Tar, true)]
[InlineData("Tar.LongPathsWithLongNameExtension.tar", ArchiveType.Tar, true)]
[InlineData("Tar.mod.tar", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar.bz2", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar.lz", ArchiveType.Tar, true)]
[InlineData("Tar.oldgnu.tar.gz", ArchiveType.Tar, true)]
[InlineData("Tar.tar", ArchiveType.Tar, true)]
[InlineData("Tar.tar.Z", ArchiveType.Tar, true)]
[InlineData("Tar.tar.bz2", ArchiveType.Tar, true)]
[InlineData("Tar.tar.gz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.lz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.xz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.zst", ArchiveType.Tar, true)]
[InlineData("TarCorrupted.tar", ArchiveType.Tar, true)]
[InlineData("TarWithSymlink.tar.gz", ArchiveType.Tar, true)]
[InlineData("WinZip26.zip", ArchiveType.Zip, true)]
[InlineData("WinZip26_BZip2.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip26_LZMA.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip27_XZ.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip27_ZSTD.zipx", ArchiveType.Zip, true)]
[InlineData("Zip.644.zip", ArchiveType.Zip, true)]
[InlineData("Zip.EntryComment.zip", ArchiveType.Zip, true)]
[InlineData("Zip.Evil.zip", ArchiveType.Zip, true)]
[InlineData("Zip.LongComment.zip", ArchiveType.Zip, true)]
[InlineData("Zip.UnicodePathExtra.zip", ArchiveType.Zip, true)]
[InlineData("Zip.badlocalextra.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.pkware.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.WinzipAES.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.WinzipAES2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.dd-.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.mod.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.mod2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.pkware.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate64.zip", ArchiveType.Zip, true)]
[InlineData("Zip.implode.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.WinzipAES.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.empty.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.datadescriptors.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.encrypted.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.issue86.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce1.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce3.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce4.zip", ArchiveType.Zip, true)]
[InlineData("Zip.shrink.zip", ArchiveType.Zip, true)]
[InlineData("Zip.uncompressed.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zip64.compressedonly.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zip64.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zipx", ArchiveType.Zip, true)]
[InlineData("Zip.zstd.WinzipAES.mixed.zip", ArchiveType.Zip, true)]
[InlineData("large_test.txt.Z", ArchiveType.Lzw, false)]
[InlineData("test_477.zip", ArchiveType.Zip, true)]
[InlineData("ustar with long names.tar", ArchiveType.Tar, true)]
[InlineData("very long filename.tar", ArchiveType.Tar, true)]
[InlineData("zipcrypto.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.AES.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.Encrypted.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.Encrypted2.zip", ArchiveType.Zip, true)]
public void GetArchiveInformation_DetectsSingleFileTestArchives(
string archiveName,
ArchiveType expectedType,
bool expectedSeekable
)
{
var info = ArchiveFactory.GetArchiveInformation(GetTestArchivePath(archiveName));
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedSeekable, info.SupportsRandomAccess);
}
[Theory]
[InlineData("64bitstream.zip.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARM.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARM64.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ARMT.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BCJ.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BCJ2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.BZip2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Copy.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.EmptyStream.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Filters.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.IA64.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA.Aes.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA2.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.LZMA2.Aes.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.PPC.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.PPMd.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.RISCV.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.SPARC.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.Tar.tar", ArchiveType.Tar, true)]
[InlineData("7Zip.Tar.tar.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.ZSTD.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.delta.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.delta.distance.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.encryptedFiles.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.eos.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.nonsolid.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.solid.1block.7z", ArchiveType.SevenZip, true)]
[InlineData("7Zip.solid.7z", ArchiveType.SevenZip, true)]
[InlineData("Ace.encrypted.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method1-solid.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method1.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method2-solid.ace", ArchiveType.Ace, false)]
[InlineData("Ace.method2.ace", ArchiveType.Ace, false)]
[InlineData("Ace.store.ace", ArchiveType.Ace, false)]
[InlineData("Ace.store.largefile.ace", ArchiveType.Ace, false)]
[InlineData("Arc.crunched.arc", ArchiveType.Arc, false)]
[InlineData("Arc.crunched.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squashed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squashed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squeezed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.squeezed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arc.uncompressed.arc", ArchiveType.Arc, false)]
[InlineData("Arc.uncompressed.largefile.arc", ArchiveType.Arc, false)]
[InlineData("Arj.encrypted.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method1.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method1.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method2.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method2.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method3.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method3.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method4.arj", ArchiveType.Arj, false)]
[InlineData("Arj.method4.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Arj.store.arj", ArchiveType.Arj, false)]
[InlineData("Arj.store.largefile.arj", ArchiveType.Arj, false)]
[InlineData("Issue_685.zip", ArchiveType.Zip, true)]
[InlineData("PrePostHeaders.zip", ArchiveType.Zip, true)]
[InlineData("Rar.Audio_program.rar", ArchiveType.Rar, true)]
[InlineData("Rar.Encrypted.rar", ArchiveType.Rar, true)]
[InlineData("Rar.comment.rar", ArchiveType.Rar, true)]
[InlineData("Rar.encrypted_filesAndHeader.rar", ArchiveType.Rar, true)]
[InlineData("Rar.encrypted_filesOnly.rar", ArchiveType.Rar, true)]
[InlineData("Rar.issue1050.rar", ArchiveType.Rar, true)]
[InlineData("Rar.malformed_512byte.rar", ArchiveType.Rar, true)]
[InlineData("Rar.none.rar", ArchiveType.Rar, true)]
[InlineData("Rar.rar", ArchiveType.Rar, true)]
[InlineData("Rar.solid.rar", ArchiveType.Rar, true)]
[InlineData("Rar.test_invalid_exttime.rar", ArchiveType.Rar, true)]
[InlineData("Rar15.rar", ArchiveType.Rar, true)]
[InlineData("Rar2.rar", ArchiveType.Rar, true)]
[InlineData("Rar4.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.comment.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.crc_blake2.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.encrypted_filesAndHeader.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.encrypted_filesOnly.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.none.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.rar", ArchiveType.Rar, true)]
[InlineData("Rar5.solid.rar", ArchiveType.Rar, true)]
[InlineData("Tar.ContainsRar.tar", ArchiveType.Tar, true)]
[InlineData("Tar.ContainsTarGz.tar", ArchiveType.Tar, true)]
[InlineData("Tar.Empty.tar", ArchiveType.Tar, true)]
[InlineData("Tar.LongPathsWithLongNameExtension.tar", ArchiveType.Tar, true)]
[InlineData("Tar.mod.tar", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar.bz2", ArchiveType.Tar, true)]
[InlineData("Tar.noEmptyDirs.tar.lz", ArchiveType.Tar, true)]
[InlineData("Tar.oldgnu.tar.gz", ArchiveType.Tar, true)]
[InlineData("Tar.tar", ArchiveType.Tar, true)]
[InlineData("Tar.tar.Z", ArchiveType.Tar, true)]
[InlineData("Tar.tar.bz2", ArchiveType.Tar, true)]
[InlineData("Tar.tar.gz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.lz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.xz", ArchiveType.Tar, true)]
[InlineData("Tar.tar.zst", ArchiveType.Tar, true)]
[InlineData("TarCorrupted.tar", ArchiveType.Tar, true)]
[InlineData("TarWithSymlink.tar.gz", ArchiveType.Tar, true)]
[InlineData("WinZip26.zip", ArchiveType.Zip, true)]
[InlineData("WinZip26_BZip2.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip26_LZMA.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip27_XZ.zipx", ArchiveType.Zip, true)]
[InlineData("WinZip27_ZSTD.zipx", ArchiveType.Zip, true)]
[InlineData("Zip.644.zip", ArchiveType.Zip, true)]
[InlineData("Zip.EntryComment.zip", ArchiveType.Zip, true)]
[InlineData("Zip.Evil.zip", ArchiveType.Zip, true)]
[InlineData("Zip.LongComment.zip", ArchiveType.Zip, true)]
[InlineData("Zip.UnicodePathExtra.zip", ArchiveType.Zip, true)]
[InlineData("Zip.badlocalextra.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.pkware.zip", ArchiveType.Zip, true)]
[InlineData("Zip.bzip2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.WinzipAES.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.WinzipAES2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.dd-.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.mod.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.mod2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.pkware.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate.zip", ArchiveType.Zip, true)]
[InlineData("Zip.deflate64.zip", ArchiveType.Zip, true)]
[InlineData("Zip.implode.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.WinzipAES.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.empty.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.lzma.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.datadescriptors.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.encrypted.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.issue86.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.none.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.dd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.noEmptyDirs.zip", ArchiveType.Zip, true)]
[InlineData("Zip.ppmd.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce1.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce2.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce3.zip", ArchiveType.Zip, true)]
[InlineData("Zip.reduce4.zip", ArchiveType.Zip, true)]
[InlineData("Zip.shrink.zip", ArchiveType.Zip, true)]
[InlineData("Zip.uncompressed.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zip64.compressedonly.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zip64.zip", ArchiveType.Zip, true)]
[InlineData("Zip.zipx", ArchiveType.Zip, true)]
[InlineData("Zip.zstd.WinzipAES.mixed.zip", ArchiveType.Zip, true)]
[InlineData("large_test.txt.Z", ArchiveType.Lzw, false)]
[InlineData("test_477.zip", ArchiveType.Zip, true)]
[InlineData("ustar with long names.tar", ArchiveType.Tar, true)]
[InlineData("very long filename.tar", ArchiveType.Tar, true)]
[InlineData("zipcrypto.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.AES.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.Encrypted.zip", ArchiveType.Zip, true)]
[InlineData("SharpCompress.Encrypted2.zip", ArchiveType.Zip, true)]
public async ValueTask GetArchiveInformationAsync_DetectsSingleFileTestArchives(
string archiveName,
ArchiveType expectedType,
bool expectedSeekable
)
{
var info = await ArchiveFactory.GetArchiveInformationAsync(GetTestArchivePath(archiveName));
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(expectedSeekable, info.SupportsRandomAccess);
}
[Fact]
public void GetArchiveInformation_ReturnsNull_ForNonArchive()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
var info = ArchiveFactory.GetArchiveInformation(stream);
Assert.Null(info);
}
[Fact]
public async ValueTask GetArchiveInformationAsync_ReturnsNull_ForNonArchive()
{
using var stream = new MemoryStream(Encoding.ASCII.GetBytes("not an archive"));
var info = await ArchiveFactory.GetArchiveInformationAsync(stream);
Assert.Null(info);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
public void GetArchiveInformation_Stream_PreservesPosition(
string archiveName,
ArchiveType expectedType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 13);
var startPosition = stream.Position;
var info = ArchiveFactory.GetArchiveInformation(stream);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(startPosition, stream.Position);
}
[Theory]
[InlineData("Zip.deflate.zip", ArchiveType.Zip)]
[InlineData("Tar.noEmptyDirs.tar", ArchiveType.Tar)]
public async ValueTask GetArchiveInformationAsync_Stream_PreservesPosition(
string archiveName,
ArchiveType expectedType
)
{
using var stream = CreatePrefixedArchiveStream(archiveName, 13);
var startPosition = stream.Position;
var info = await ArchiveFactory.GetArchiveInformationAsync(stream);
Assert.NotNull(info);
Assert.Equal(expectedType, info.Type);
Assert.Equal(startPosition, stream.Position);
}
private MemoryStream CreatePrefixedArchiveStream(string archiveName, int prefixLength)
{
var archiveBytes = File.ReadAllBytes(GetTestArchivePath(archiveName));
var buffer = new byte[prefixLength + archiveBytes.Length];
archiveBytes.CopyTo(buffer, prefixLength);
var stream = new MemoryStream(buffer);
stream.Position = prefixLength;
return stream;
}
private static string GetTestArchivePath(string archiveName)
{
var archivesPath = Path.Combine(TEST_ARCHIVES_PATH, archiveName);
if (File.Exists(archivesPath))
{
return archivesPath;
}
return Path.GetFullPath(Path.Combine(TEST_ARCHIVES_PATH, "..", archiveName));
}
}

View File

@@ -179,7 +179,7 @@ public class ArchiveTests : ReaderTests
{
using (
var archive = ArchiveFactory.OpenArchive(
testArchives.Select(a => new FileInfo(a)),
testArchives.Select(a => new FileInfo(a)).ToArray(),
readerOptions
)
)
@@ -208,7 +208,7 @@ public class ArchiveTests : ReaderTests
{
using (
var archive = ArchiveFactory.OpenArchive(
testArchives.Select(f => new FileInfo(f)),
testArchives.Select(f => new FileInfo(f)).ToArray(),
readerOptions
)
)
@@ -240,7 +240,7 @@ public class ArchiveTests : ReaderTests
{
var src = testArchives.ToArray();
using var archive = ArchiveFactory.OpenArchive(
src.Select(f => new FileInfo(f)),
src.Select(f => new FileInfo(f)).ToArray(),
readerOptions
);
var idx = 0;

View File

@@ -94,7 +94,7 @@ public class ArjReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(testArchive);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions()
ReaderOptions.ForExternalStream
);
while (await reader.MoveToNextEntryAsync())
{
@@ -119,7 +119,10 @@ public class ArjReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(testArchive);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions() { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (await reader.MoveToNextEntryAsync())
{

View File

@@ -332,7 +332,10 @@ public class CompressionProviderTests
);
compressedStream.Position = 0;
var readerOptions = new ReaderOptions { ArchiveEncoding = archiveEncoding };
var readerOptions = ReaderOptions.ForExternalStream with
{
ArchiveEncoding = archiveEncoding,
};
var context = CompressionContext.FromStream(compressedStream) with
{
ReaderOptions = readerOptions,
@@ -433,7 +436,7 @@ public class CompressionProviderTests
archiveStream.Position = 0;
var customProvider = new GZipCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
var readOptions = new ReaderOptions { Providers = registry };
var readOptions = ReaderOptions.ForExternalStream.WithProviders(registry);
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
@@ -462,7 +465,7 @@ public class CompressionProviderTests
archiveStream.Position = 0;
var registry = CompressionProviderRegistry.Default.With(new ContextRequiredGZipProvider());
var readOptions = new ReaderOptions { Providers = registry };
var readOptions = ReaderOptions.ForExternalStream.WithProviders(registry);
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
@@ -504,7 +507,11 @@ public class CompressionProviderTests
var customProvider = new DeflateCompressionProvider();
var registry = CompressionProviderRegistry.Default.With(customProvider);
var original = new ReaderOptions { Providers = registry, LeaveStreamOpen = false };
var original = ReaderOptions.ForExternalStream with
{
Providers = registry,
LeaveStreamOpen = false,
};
// Clone using 'with' expression
var clone = original with
@@ -533,7 +540,7 @@ public class CompressionProviderTests
var trackingProvider = new TrackingCompressionProvider(new GZipCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var readOptions = new ReaderOptions { Providers = registry };
var readOptions = ReaderOptions.ForExternalStream.WithProviders(registry);
archiveStream.Position = 0;
using var archive = TarArchive.OpenArchive(archiveStream, readOptions);
@@ -562,7 +569,7 @@ public class CompressionProviderTests
var trackingProvider = new TrackingCompressionProvider(new GZipCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var readOptions = new ReaderOptions { Providers = registry };
var readOptions = ReaderOptions.ForExternalStream.WithProviders(registry);
archiveStream.Position = 0;
await using var archive = await TarArchive.OpenAsyncArchive(archiveStream, readOptions);
@@ -600,7 +607,7 @@ public class CompressionProviderTests
var trackingProvider = new TrackingCompressionProvider(new DeflateCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var options = new ReaderOptions { Providers = registry };
var options = ReaderOptions.ForExternalStream.WithProviders(registry);
zipStream.Position = 0;
await using var reader = await ReaderFactory.OpenAsyncReader(zipStream, options);
@@ -618,7 +625,7 @@ public class CompressionProviderTests
var archivePath = Path.Combine(TestBase.TEST_ARCHIVES_PATH, "Tar.tar.Z");
var trackingProvider = new TrackingCompressionProvider(new LzwCompressionProvider());
var registry = CompressionProviderRegistry.Default.With(trackingProvider);
var options = new ReaderOptions { Providers = registry };
var options = ReaderOptions.ForExternalStream.WithProviders(registry);
using var stream = File.OpenRead(archivePath);
using var reader = ReaderFactory.OpenReader(stream, options);
@@ -809,7 +816,7 @@ public class CompressionProviderTests
// Read back using internal provider (should be compatible)
archiveStream.Position = 0;
var readOptions = new ReaderOptions();
var readOptions = ReaderOptions.ForExternalStream;
using var reader = TarReader.OpenReader(archiveStream, readOptions);
reader.MoveToNextEntry().Should().BeTrue();
using var entryStream = reader.OpenEntryStream();

View File

@@ -5,6 +5,7 @@ using SharpCompress.Archives;
using SharpCompress.Archives.GZip;
using SharpCompress.Archives.Tar;
using SharpCompress.Common;
using SharpCompress.Test.Mocks;
using SharpCompress.Writers.GZip;
using Xunit;
@@ -127,6 +128,23 @@ public class GZipArchiveTests : ArchiveTests
Assert.Equal(archive.Type, ArchiveType.GZip);
}
[Fact]
public void GZipArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() => GZipArchive.OpenArchive([nonSeekable, seekable]));
}
[Fact]
public void GZipArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => GZipArchive.OpenArchive(unreadable));
}
[Fact]
public void GZip_Archive_NonSeekableStream()
{

View File

@@ -23,7 +23,7 @@ public class LzwReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "large_test.txt.Z"));
using var reader = LzwReader.OpenReader(stream);
Assert.Equal(ArchiveType.Lzw, reader.ArchiveType);
Assert.Equal(ArchiveType.Lzw, reader.Type);
Assert.True(reader.MoveToNextEntry());
var entry = reader.Entry;

View File

@@ -37,11 +37,14 @@ public class LzwReaderTests : ReaderTests
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.Z"));
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LeaveStreamOpen = false }
ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = false,
}
);
// Should detect as Tar archive with Lzw compression
Assert.Equal(ArchiveType.Tar, reader.ArchiveType);
Assert.Equal(ArchiveType.Tar, reader.Type);
Assert.True(reader.MoveToNextEntry());
Assert.NotNull(reader.Entry);
Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType);
@@ -80,7 +83,7 @@ public class LzwReaderTests : ReaderTests
using var reader = ReaderFactory.OpenReader(stream);
// Should detect as Lzw archive (not Tar)
Assert.Equal(ArchiveType.Lzw, reader.ArchiveType);
Assert.Equal(ArchiveType.Lzw, reader.Type);
Assert.True(reader.MoveToNextEntry());
Assert.NotNull(reader.Entry);
Assert.Equal(CompressionType.Lzw, reader.Entry.CompressionType);

View File

@@ -160,8 +160,8 @@ public class OptionsUsabilityTests : TestBase
[Fact]
public void ReaderOptions_Fluent_Methods_Modify_Correctly()
{
var options = new ReaderOptions()
.WithLeaveStreamOpen(false)
var options = ReaderOptions
.ForExternalStream.WithLeaveStreamOpen(false)
.WithPassword("secret")
.WithLookForHeader(true)
.WithBufferSize(65536);
@@ -176,15 +176,15 @@ public class OptionsUsabilityTests : TestBase
public void ReaderOptions_Fluent_And_Initializer_Equivalent()
{
// Fluent approach
var fluentApproach = new ReaderOptions()
.WithLeaveStreamOpen(false)
var fluentApproach = ReaderOptions
.ForExternalStream.WithLeaveStreamOpen(false)
.WithPassword("secret")
.WithLookForHeader(true)
.WithBufferSize(65536)
.WithDisableCheckIncomplete(true);
// Object initializer approach
var initializerApproach = new ReaderOptions
// Preset + with-expression approach
var initializerApproach = ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = false,
Password = "secret",

View File

@@ -108,7 +108,7 @@ public class ProgressReportTests : TestBase
// Now read it with progress reporting
archiveStream.Position = 0;
var readerOptions = new ReaderOptions { Progress = progress };
var readerOptions = ReaderOptions.ForExternalStream.WithProgress(progress);
using (var reader = ReaderFactory.OpenReader(archiveStream, readerOptions))
{
@@ -234,7 +234,7 @@ public class ProgressReportTests : TestBase
// Read without progress
archiveStream.Position = 0;
var readerOptions = new ReaderOptions();
var readerOptions = ReaderOptions.ForExternalStream;
Assert.Null(readerOptions.Progress);
using (var reader = ReaderFactory.OpenReader(archiveStream, readerOptions))
@@ -324,7 +324,7 @@ public class ProgressReportTests : TestBase
// Now read it with progress reporting
archiveStream.Position = 0;
var readerOptions = new ReaderOptions { Progress = progress };
var readerOptions = ReaderOptions.ForExternalStream.WithProgress(progress);
using (var reader = ReaderFactory.OpenReader(archiveStream, readerOptions))
{
@@ -445,7 +445,7 @@ public class ProgressReportTests : TestBase
// Now read it with progress reporting
archiveStream.Position = 0;
var readerOptions = new ReaderOptions { Progress = progress };
var readerOptions = ReaderOptions.ForExternalStream.WithProgress(progress);
using (var reader = ReaderFactory.OpenReader(archiveStream, readerOptions))
{
@@ -538,7 +538,7 @@ public class ProgressReportTests : TestBase
// Now read it with progress reporting
archiveStream.Position = 0;
var readerOptions = new ReaderOptions { Progress = progress };
var readerOptions = ReaderOptions.ForExternalStream.WithProgress(progress);
await using (
var reader = await ReaderFactory.OpenAsyncReader(

View File

@@ -96,7 +96,11 @@ public class RarArchiveAsyncTests : ArchiveTests
await using (
var archive = await RarArchive.OpenAsyncArchive(
stream,
new ReaderOptions { Password = password, LeaveStreamOpen = true }
ReaderOptions.ForExternalStream with
{
Password = password,
LeaveStreamOpen = true,
}
)
)
{
@@ -123,7 +127,11 @@ public class RarArchiveAsyncTests : ArchiveTests
using (
var archive = RarArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, archiveName),
new ReaderOptions { Password = password, LeaveStreamOpen = true }
ReaderOptions.ForFilePath with
{
Password = password,
LeaveStreamOpen = true,
}
)
)
{
@@ -169,7 +177,13 @@ public class RarArchiveAsyncTests : ArchiveTests
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg"));
using (
var archive = RarArchive.OpenArchive(stream, new ReaderOptions { LookForHeader = true })
var archive = RarArchive.OpenArchive(
stream,
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
@@ -278,7 +292,10 @@ public class RarArchiveAsyncTests : ArchiveTests
private async ValueTask DoRar_Multi_ArchiveStreamReadAsync(string[] archives, bool isSolid)
{
using var archive = RarArchive.OpenArchive(
archives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)).Select(File.OpenRead)
archives
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
.Select(File.OpenRead)
.ToArray()
);
Assert.Equal(archive.IsSolid, isSolid);
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
@@ -338,7 +355,10 @@ public class RarArchiveAsyncTests : ArchiveTests
using (
var archive = RarArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg"),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForFilePath with
{
LookForHeader = true,
}
)
)
{
@@ -697,7 +717,7 @@ public class RarArchiveAsyncTests : ArchiveTests
{
var paths = testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x));
using var archive = ArchiveFactory.OpenArchive(
paths.Select(a => new FileInfo(a)),
paths.Select(a => new FileInfo(a)).ToArray(),
readerOptions
);
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
@@ -755,7 +775,7 @@ public class RarArchiveAsyncTests : ArchiveTests
{
var paths = testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x));
using var archive = ArchiveFactory.OpenArchive(
paths.Select(f => new FileInfo(f)),
paths.Select(f => new FileInfo(f)).ToArray(),
readerOptions
);
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))

View File

@@ -92,7 +92,11 @@ public class RarArchiveTests : ArchiveTests
using (
var archive = RarArchive.OpenArchive(
stream,
new ReaderOptions { Password = password, LeaveStreamOpen = true }
ReaderOptions.ForExternalStream with
{
Password = password,
LeaveStreamOpen = true,
}
)
)
{
@@ -119,7 +123,11 @@ public class RarArchiveTests : ArchiveTests
using (
var archive = RarArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, archiveName),
new ReaderOptions { Password = password, LeaveStreamOpen = true }
ReaderOptions.ForFilePath with
{
Password = password,
LeaveStreamOpen = true,
}
)
)
{
@@ -140,6 +148,23 @@ public class RarArchiveTests : ArchiveTests
[Fact]
public void Rar_ArchiveStreamRead() => ArchiveStreamRead("Rar.rar");
[Fact]
public void RarArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() => RarArchive.OpenArchive([nonSeekable, seekable]));
}
[Fact]
public void RarArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => RarArchive.OpenArchive(unreadable));
}
[Fact]
public void Rar5_ArchiveStreamRead() => ArchiveStreamRead("Rar5.rar");
@@ -162,7 +187,13 @@ public class RarArchiveTests : ArchiveTests
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg"));
using (
var archive = RarArchive.OpenArchive(stream, new ReaderOptions { LookForHeader = true })
var archive = RarArchive.OpenArchive(
stream,
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
@@ -268,7 +299,10 @@ public class RarArchiveTests : ArchiveTests
private void DoRar_Multi_ArchiveStreamRead(string[] archives, bool isSolid)
{
using var archive = RarArchive.OpenArchive(
archives.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s)).Select(File.OpenRead)
archives
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
.Select(File.OpenRead)
.ToArray()
);
Assert.Equal(archive.IsSolid, isSolid);
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
@@ -325,7 +359,10 @@ public class RarArchiveTests : ArchiveTests
using (
var archive = RarArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg"),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForFilePath with
{
LookForHeader = true,
}
)
)
{
@@ -774,7 +811,7 @@ public class RarArchiveTests : ArchiveTests
public void Rar_MalformedArchive_NoInfiniteLoop()
{
var testFile = "Rar.malformed_512byte.rar";
var readerOptions = new ReaderOptions { LookForHeader = true };
var readerOptions = ReaderOptions.ForExternalStream.WithLookForHeader(true);
// This should throw InvalidOperationException, not hang in an infinite loop
var exception = Assert.Throws<ArchiveOperationException>(() =>

View File

@@ -16,7 +16,10 @@ public class RarHeaderFactoryTest : TestBase
public RarHeaderFactoryTest() =>
_rarHeaderFactory = new RarHeaderFactory(
StreamingMode.Seekable,
new ReaderOptions { LeaveStreamOpen = true }
ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = true,
}
);
[Fact]

View File

@@ -97,7 +97,10 @@ public class RarReaderAsyncTests : ReaderTests
archives
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
.Select(p => File.OpenRead(p)),
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
@@ -211,7 +214,10 @@ public class RarReaderAsyncTests : ReaderTests
await ReadAsync(
testArchive,
CompressionType.Rar,
new ReaderOptions { Password = password }
ReaderOptions.ForFilePath with
{
Password = password,
}
);
[Fact]
@@ -272,7 +278,10 @@ public class RarReaderAsyncTests : ReaderTests
await using (
var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
@@ -295,7 +304,10 @@ public class RarReaderAsyncTests : ReaderTests
using (
IReader baseReader = RarReader.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
@@ -338,7 +350,10 @@ public class RarReaderAsyncTests : ReaderTests
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, filename));
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (await reader.MoveToNextEntryAsync())
{
@@ -361,7 +376,10 @@ public class RarReaderAsyncTests : ReaderTests
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, filename));
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (await reader.MoveToNextEntryAsync())
{
@@ -383,7 +401,7 @@ public class RarReaderAsyncTests : ReaderTests
using Stream stream = File.OpenRead(testArchive);
await using var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
readerOptions ?? new ReaderOptions()
readerOptions ?? ReaderOptions.ForExternalStream
);
while (await reader.MoveToNextEntryAsync())
{

View File

@@ -71,7 +71,10 @@ public class RarReaderTests : ReaderTests
archives
.Select(s => Path.Combine(TEST_ARCHIVES_PATH, s))
.Select(p => File.OpenRead(p)),
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
@@ -173,7 +176,14 @@ public class RarReaderTests : ReaderTests
public void Rar5_Encrypted_Reader() => ReadRar("Rar5.encrypted_filesOnly.rar", "test");
private void ReadRar(string testArchive, string password) =>
Read(testArchive, CompressionType.Rar, new ReaderOptions { Password = password });
Read(
testArchive,
CompressionType.Rar,
ReaderOptions.ForFilePath with
{
Password = password,
}
);
[Fact]
public void Rar_Entry_Stream() => DoRar_Entry_Stream("Rar.rar");
@@ -222,7 +232,10 @@ public class RarReaderTests : ReaderTests
using (
var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
@@ -243,7 +256,13 @@ public class RarReaderTests : ReaderTests
{
using (var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Rar.jpeg.jpg")))
using (
var reader = RarReader.OpenReader(stream, new ReaderOptions { LookForHeader = true })
var reader = RarReader.OpenReader(
stream,
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
)
)
{
while (reader.MoveToNextEntry())
@@ -278,7 +297,10 @@ public class RarReaderTests : ReaderTests
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, filename));
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (reader.MoveToNextEntry())
{
@@ -301,7 +323,10 @@ public class RarReaderTests : ReaderTests
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, filename));
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (reader.MoveToNextEntry())
{
@@ -321,7 +346,10 @@ public class RarReaderTests : ReaderTests
);
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (reader.MoveToNextEntry())
{

View File

@@ -0,0 +1,41 @@
using System;
using System.IO;
using System.Threading.Tasks;
using SharpCompress.Readers;
using SharpCompress.Readers.Rar;
using SharpCompress.Test.Mocks;
using Xunit;
namespace SharpCompress.Test;
public class ReaderFactoryTests
{
[Fact]
public void OpenReader_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => ReaderFactory.OpenReader(unreadable));
}
[Fact]
public async ValueTask OpenAsyncReader_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
await Assert.ThrowsAsync<ArgumentException>(() =>
ReaderFactory.OpenAsyncReader(unreadable).AsTask()
);
}
[Fact]
public void RarReader_StreamCollection_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
using var readable = new MemoryStream();
Assert.Throws<ArgumentException>(() =>
RarReader.OpenReader([unreadable, readable]).MoveToNextEntry()
);
}
}

View File

@@ -32,12 +32,12 @@ public abstract class ReaderTests : TestBase
)
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
options ??= new ReaderOptions { BufferSize = 0x20000 };
options ??= ReaderOptions.ForFilePath.WithBufferSize(0x20000);
var optionsWithStreamOpen = options with { LeaveStreamOpen = true };
var optionsWithStreamOpen = options.WithLeaveStreamOpen(true);
readImpl(testArchive, optionsWithStreamOpen);
var optionsWithStreamClosed = options with { LeaveStreamOpen = false };
var optionsWithStreamClosed = options.WithLeaveStreamOpen(false);
readImpl(testArchive, optionsWithStreamClosed);
VerifyFiles();
@@ -103,7 +103,7 @@ public abstract class ReaderTests : TestBase
(
await factory.IsArchiveAsync(
new FileInfo(testArchive).OpenRead(),
null,
ReaderOptions.ForExternalStream,
cancellationToken
)
)
@@ -112,6 +112,7 @@ public abstract class ReaderTests : TestBase
(
await factory.IsArchiveAsync(
new FileInfo(testArchive).OpenRead(),
ReaderOptions.ForExternalStream,
cancellationToken: cancellationToken
)
)
@@ -128,9 +129,9 @@ public abstract class ReaderTests : TestBase
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
options ??= new ReaderOptions() { BufferSize = 0x20000 };
options ??= ReaderOptions.ForExternalStream.WithBufferSize(0x20000);
var optionsWithStreamOpen = options with { LeaveStreamOpen = true };
var optionsWithStreamOpen = options.WithLeaveStreamOpen(true);
await ReadImplAsync(
testArchive,
expectedCompression,
@@ -138,7 +139,7 @@ public abstract class ReaderTests : TestBase
cancellationToken
);
var optionsWithStreamClosed = options with { LeaveStreamOpen = false };
var optionsWithStreamClosed = options.WithLeaveStreamOpen(false);
await ReadImplAsync(
testArchive,
expectedCompression,
@@ -215,7 +216,10 @@ public abstract class ReaderTests : TestBase
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, fileName));
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LookForHeader = true }
ReaderOptions.ForExternalStream with
{
LookForHeader = true,
}
);
while (reader.MoveToNextEntry())

View File

@@ -7,6 +7,7 @@ using SharpCompress.Common;
using SharpCompress.Common.SevenZip;
using SharpCompress.Factories;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using Xunit;
namespace SharpCompress.Test.SevenZip;
@@ -25,18 +26,49 @@ public class SevenZipArchiveTests : ArchiveTests
[Fact]
public void SevenZipArchive_LZMA_PathRead() => ArchiveFileRead("7Zip.LZMA.7z");
[Fact]
public void SevenZipArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() =>
SevenZipArchive.OpenArchive([nonSeekable, seekable])
);
}
[Fact]
public void SevenZipArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => SevenZipArchive.OpenArchive(unreadable));
}
[Fact]
public void SevenZipArchive_LZMAAES_StreamRead() =>
ArchiveStreamRead("7Zip.LZMA.Aes.7z", new ReaderOptions { Password = "testpassword" });
ArchiveStreamRead(
"7Zip.LZMA.Aes.7z",
ReaderOptions.ForExternalStream with
{
Password = "testpassword",
}
);
[Fact]
public void SevenZipArchive_LZMAAES_PathRead() =>
ArchiveFileRead("7Zip.LZMA.Aes.7z", new ReaderOptions { Password = "testpassword" });
ArchiveFileRead(
"7Zip.LZMA.Aes.7z",
ReaderOptions.ForFilePath with
{
Password = "testpassword",
}
);
[Fact]
public void SevenZipArchive_LZMAAES_NoPasswordExceptionTest() =>
Assert.Throws<CryptographicException>(() =>
ArchiveFileRead("7Zip.LZMA.Aes.7z", new ReaderOptions { Password = null })
ArchiveFileRead("7Zip.LZMA.Aes.7z", ReaderOptions.ForFilePath.WithPassword(null))
); //was failing with ArgumentNullException not CryptographicException like rar
[Fact]
@@ -57,19 +89,39 @@ public class SevenZipArchiveTests : ArchiveTests
[Fact]
public void SevenZipArchive_LZMA2_EXE_StreamRead() =>
ArchiveStreamRead(new SevenZipFactory(), "7Zip.LZMA2.exe", new() { LookForHeader = true });
ArchiveStreamRead(
new SevenZipFactory(),
"7Zip.LZMA2.exe",
ReaderOptions.ForExternalStream.WithLookForHeader(true)
);
[Fact]
public void SevenZipArchive_LZMA2_EXE_PathRead() =>
ArchiveFileRead("7Zip.LZMA2.exe", new() { LookForHeader = true }, new SevenZipFactory());
ArchiveFileRead(
"7Zip.LZMA2.exe",
ReaderOptions.ForFilePath.WithLookForHeader(true),
new SevenZipFactory()
);
[Fact]
public void SevenZipArchive_LZMA2AES_StreamRead() =>
ArchiveStreamRead("7Zip.LZMA2.Aes.7z", new ReaderOptions { Password = "testpassword" });
ArchiveStreamRead(
"7Zip.LZMA2.Aes.7z",
ReaderOptions.ForExternalStream with
{
Password = "testpassword",
}
);
[Fact]
public void SevenZipArchive_LZMA2AES_PathRead() =>
ArchiveFileRead("7Zip.LZMA2.Aes.7z", new ReaderOptions { Password = "testpassword" });
ArchiveFileRead(
"7Zip.LZMA2.Aes.7z",
ReaderOptions.ForFilePath with
{
Password = "testpassword",
}
);
[Fact]
public void SevenZipArchive_BZip2_StreamRead() => ArchiveStreamRead("7Zip.BZip2.7z");

View File

@@ -76,7 +76,10 @@ public class DisposalTests
new SourceStream(
stream,
i => null,
new ReaderOptions { LeaveStreamOpen = leaveOpen }
ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = leaveOpen,
}
)
);
}

View File

@@ -0,0 +1,356 @@
using System;
using System.Buffers;
using System.IO;
using SharpCompress.IO;
using Xunit;
namespace SharpCompress.Test.Streams;
public class PooledMemoryStreamTests
{
[Fact]
public void GrowsUsingFixedSizeBlocks()
{
var pool = new TrackingArrayPool();
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, arrayPool: pool);
stream.Write(new byte[20], 0, 20);
Assert.Equal(3, pool.RentRequests.Count);
Assert.All(pool.RentRequests, requested => Assert.Equal(8, requested));
}
[Fact]
public void DisposeReturnsRentedBlocksToPool()
{
var pool = new TrackingArrayPool();
var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, arrayPool: pool);
stream.Write(new byte[17], 0, 17);
stream.Dispose();
Assert.Equal(pool.RentRequests.Count, pool.ReturnedLengths.Count);
Assert.All(pool.ReturnedLengths, length => Assert.Equal(8, length));
}
[Fact]
public void OverRentedBlocksUseLogicalBlockSize()
{
var pool = new FilledOverRentingArrayPool(extraLength: 8, fillValue: 0x5A);
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, arrayPool: pool);
stream.Write(new byte[] { 1, 2, 3, 4, 5 }, 0, 5);
stream.Position = 10;
stream.Write(new byte[] { 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 }, 0, 10);
Assert.Equal(3, pool.RentRequests.Count);
Assert.All(pool.RentRequests, requested => Assert.Equal(8, requested));
Assert.All(pool.RentedLengths, length => Assert.Equal(16, length));
var expected = new byte[]
{
1,
2,
3,
4,
5,
0,
0,
0,
0,
0,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
};
Assert.Equal(expected, stream.ToArray());
stream.Position = 0;
var roundTrip = new byte[expected.Length];
Assert.Equal(expected.Length, stream.Read(roundTrip, 0, roundTrip.Length));
Assert.Equal(expected, roundTrip);
}
[Fact]
public void GetBufferReturnsArraySizedToCapacityWithoutTouchingPool()
{
var pool = new OverRentingArrayPool(extraLength: 8);
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, arrayPool: pool);
stream.Write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 0, 10);
var rentsBefore = pool.RentRequests.Count;
var returnsBefore = pool.ReturnedLengths.Count;
var buffer = stream.GetBuffer();
Assert.Equal(16, buffer.Length);
Assert.Equal(1, buffer[0]);
Assert.Equal(10, buffer[9]);
Assert.Equal(0, buffer[10]);
Assert.Equal(0, buffer[15]);
Assert.Equal(rentsBefore, pool.RentRequests.Count);
Assert.Equal(returnsBefore, pool.ReturnedLengths.Count);
buffer[0] = 255;
stream.Position = 0;
Assert.Equal(1, stream.ReadByte());
}
[Fact]
public void TryGetBufferReturnsSegmentWhenOpen()
{
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8);
stream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
Assert.True(stream.TryGetBuffer(out var segment));
Assert.Equal(0, segment.Offset);
Assert.Equal(4, segment.Count);
Assert.Equal(1, segment.Array![0]);
}
[Fact]
public void TryGetBufferReturnsArraySizedToCapacityWithoutTouchingPool()
{
var pool = new OverRentingArrayPool(extraLength: 8);
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, arrayPool: pool);
stream.Write(new byte[] { 1, 2, 3, 4 }, 0, 4);
var rentsBefore = pool.RentRequests.Count;
var returnsBefore = pool.ReturnedLengths.Count;
Assert.True(stream.TryGetBuffer(out var segment));
Assert.Equal(0, segment.Offset);
Assert.Equal(4, segment.Count);
Assert.Equal(8, segment.Array!.Length);
Assert.Equal(1, segment.Array[0]);
Assert.Equal(4, segment.Array[3]);
Assert.Equal(0, segment.Array[4]);
Assert.Equal(0, segment.Array[7]);
Assert.Equal(rentsBefore, pool.RentRequests.Count);
Assert.Equal(returnsBefore, pool.ReturnedLengths.Count);
segment.Array[0] = 255;
stream.Position = 0;
Assert.Equal(1, stream.ReadByte());
}
[Fact]
public void CapacitySetterCanGrowAndShrinkWithinLength()
{
using var stream = new PooledMemoryStream(capacity: 16, blockSize: 8);
stream.Write(new byte[6], 0, 6);
stream.Capacity = 24;
Assert.Equal(24, stream.Capacity);
stream.Capacity = 8;
Assert.Equal(8, stream.Capacity);
}
[Fact]
public void SetLengthExtendingClearsGap()
{
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8);
stream.Position = 5;
stream.WriteByte(42);
stream.Position = 0;
var data = stream.ToArray();
Assert.Equal(6, data.Length);
Assert.Equal(0, data[0]);
Assert.Equal(0, data[4]);
Assert.Equal(42, data[5]);
}
[Fact]
public void MethodsThrowAfterDispose()
{
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8);
stream.WriteByte(1);
stream.Dispose();
Assert.Throws<ObjectDisposedException>(() => stream.ReadByte());
Assert.Throws<ObjectDisposedException>(() => stream.ToArray());
Assert.Throws<ObjectDisposedException>(() => stream.GetBuffer());
}
[Fact]
public void MultipleGetBufferCallsReturnDifferentArrays()
{
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8);
stream.Write(new byte[] { 1, 2, 3 }, 0, 3);
var buffer1 = stream.GetBuffer();
var buffer2 = stream.GetBuffer();
Assert.NotSame(buffer1, buffer2);
Assert.Equal(buffer1, buffer2);
}
[Fact]
public void SeekBeyondMaxLengthThrows()
{
using var stream = new PooledMemoryStream();
Assert.Throws<ArgumentOutOfRangeException>(() =>
stream.Seek(int.MaxValue + 1L, SeekOrigin.Begin)
);
}
[Fact]
public void DisposeAfterGetBufferDoesNotReturnExposedArrayToPool()
{
var pool = new OverRentingArrayPool(extraLength: 8);
byte[] buffer;
using (var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, pool))
{
stream.Write(new byte[] { 1, 2, 3 }, 0, 3);
buffer = stream.GetBuffer();
Assert.NotNull(buffer);
Assert.NotEmpty(pool.RentRequests);
}
Assert.DoesNotContain(buffer, pool.ReturnedArrays);
Assert.Equal(1, buffer[0]);
Assert.Equal(2, buffer[1]);
Assert.Equal(3, buffer[2]);
}
[Fact]
public void DisposeAfterTryGetBufferDoesNotReturnExposedArrayToPool()
{
var pool = new OverRentingArrayPool(extraLength: 8);
ArraySegment<byte> segment;
using (var stream = new PooledMemoryStream(capacity: 0, blockSize: 8, pool))
{
stream.Write(new byte[] { 1, 2, 3 }, 0, 3);
Assert.True(stream.TryGetBuffer(out segment));
Assert.NotNull(segment.Array);
Assert.NotEmpty(pool.RentRequests);
}
Assert.DoesNotContain(segment.Array!, pool.ReturnedArrays);
Assert.Equal(1, segment.Array![segment.Offset]);
Assert.Equal(2, segment.Array[segment.Offset + 1]);
Assert.Equal(3, segment.Array[segment.Offset + 2]);
}
[Fact]
public void SetLengthNearIntMaxValueThrowsIOExceptionWhenBlockRoundingOverflows()
{
using var stream = new PooledMemoryStream(capacity: 0, blockSize: 8);
var length = int.MaxValue - 1L;
Assert.Throws<IOException>(() => stream.SetLength(length));
Assert.Equal(0, stream.Length);
}
private sealed class TrackingArrayPool : ArrayPool<byte>
{
private const byte RentedBufferFillValue = 0x5A;
public readonly System.Collections.Generic.List<int> RentRequests = new();
public readonly System.Collections.Generic.List<int> ReturnedLengths = new();
public override byte[] Rent(int minimumLength)
{
RentRequests.Add(minimumLength);
var array = new byte[minimumLength];
for (var i = 0; i < array.Length; i++)
{
array[i] = RentedBufferFillValue;
}
return array;
}
public override void Return(byte[] array, bool clearArray = false)
{
ReturnedLengths.Add(array.Length);
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
}
}
private sealed class OverRentingArrayPool : ArrayPool<byte>
{
private readonly int _extraLength;
public OverRentingArrayPool(int extraLength)
{
_extraLength = extraLength;
}
public readonly System.Collections.Generic.List<int> RentRequests = new();
public readonly System.Collections.Generic.List<int> ReturnedLengths = new();
public readonly System.Collections.Generic.List<byte[]> ReturnedArrays = new();
public override byte[] Rent(int minimumLength)
{
RentRequests.Add(minimumLength);
return new byte[minimumLength + _extraLength];
}
public override void Return(byte[] array, bool clearArray = false)
{
ReturnedLengths.Add(array.Length);
ReturnedArrays.Add(array);
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
}
}
private sealed class FilledOverRentingArrayPool : ArrayPool<byte>
{
private readonly int _extraLength;
private readonly byte _fillValue;
public FilledOverRentingArrayPool(int extraLength, byte fillValue)
{
_extraLength = extraLength;
_fillValue = fillValue;
}
public readonly System.Collections.Generic.List<int> RentRequests = new();
public readonly System.Collections.Generic.List<int> RentedLengths = new();
public override byte[] Rent(int minimumLength)
{
RentRequests.Add(minimumLength);
var array = new byte[minimumLength + _extraLength];
RentedLengths.Add(array.Length);
for (var i = 0; i < array.Length; i++)
{
array[i] = _fillValue;
}
return array;
}
public override void Return(byte[] array, bool clearArray = false)
{
if (clearArray)
{
Array.Clear(array, 0, array.Length);
}
}
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using SharpCompress.Common;
using SharpCompress.IO;
using SharpCompress.Test.Mocks;
using Xunit;
@@ -134,10 +135,10 @@ public class SharpCompressStreamSeekTest
// Simulates the BZip2 scenario: the ring buffer must be large enough
// from the moment StartRecording is called so that a large probe read
// (up to 900 KB for BZip2) can be rewound without buffer overflow.
const int largeSize = 100;
const int largeReadSize = 80;
const int largeSize = 100_000;
const int largeReadSize = 80_000;
var data = new byte[100];
var data = new byte[largeSize];
for (var i = 0; i < data.Length; i++)
{
data[i] = (byte)(i + 1);
@@ -181,4 +182,20 @@ public class SharpCompressStreamSeekTest
Assert.Equal(1, readBuffer[0]);
Assert.Equal(5, readBuffer[4]);
}
[Fact]
public void StartRecording_WithExistingSmallerRingBuffer_Throws()
{
var ms = new MemoryStream(new byte[131_072]);
var nonSeekableMs = new NonSeekableStreamWrapper(ms);
var stream = SharpCompressStream.Create(nonSeekableMs, 32_768);
var exception = Assert.Throws<ArchiveOperationException>(() =>
stream.StartRecording(131_072)
);
Assert.Contains("ring buffer", exception.Message);
Assert.Contains("131072", exception.Message);
Assert.Contains("32768", exception.Message);
}
}

View File

@@ -22,6 +22,26 @@ public class TarArchiveAsyncTests : ArchiveTests
[Fact]
public async ValueTask TarArchiveStreamRead_Async() => await ArchiveStreamReadAsync("Tar.tar");
[Fact]
public async ValueTask TarArchiveOpenAsyncStream_Throws_On_NonSeekable_Stream()
{
using var stream = new ForwardOnlyStream(new MemoryStream());
await Assert.ThrowsAsync<ArgumentException>(() =>
TarArchive.OpenAsyncArchive(stream).AsTask()
);
}
[Fact]
public async ValueTask TarArchiveOpenAsyncStream_Throws_On_Unreadable_Stream()
{
using var stream = new TestStream(new MemoryStream(), false, true, true);
await Assert.ThrowsAsync<ArgumentException>(() =>
TarArchive.OpenAsyncArchive(stream).AsTask()
);
}
[Fact]
public async ValueTask Tar_FileName_Exactly_100_Characters_Async()
{
@@ -57,7 +77,7 @@ public class TarArchiveAsyncTests : ArchiveTests
await using (
var archive2 = await TarArchive.OpenAsyncArchive(
new AsyncOnlyStream(File.OpenRead(unmodified)),
new ReaderOptions() { LeaveStreamOpen = false }
ReaderOptions.ForExternalStream.WithLeaveStreamOpen(false)
)
)
{
@@ -115,7 +135,7 @@ public class TarArchiveAsyncTests : ArchiveTests
await using (
var archive2 = await TarArchive.OpenAsyncArchive(
new AsyncOnlyStream(File.OpenRead(unmodified)),
new ReaderOptions() { LeaveStreamOpen = false }
ReaderOptions.ForExternalStream.WithLeaveStreamOpen(false)
)
)
{
@@ -213,7 +233,7 @@ public class TarArchiveAsyncTests : ArchiveTests
}
using (var inputMemory = new MemoryStream(mstm.ToArray()))
{
var tropt = new ReaderOptions { ArchiveEncoding = enc };
var tropt = ReaderOptions.ForExternalStream.WithArchiveEncoding(enc);
await using (
var tr = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(inputMemory),

View File

@@ -34,6 +34,28 @@ public class TarArchiveTests : ArchiveTests
Assert.Throws<ArgumentException>(() => ArchiveFactory.OpenArchive(stream));
}
[Fact]
public void TarArchiveStreamRead_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(
File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar")),
false,
true,
true
);
Assert.Throws<ArgumentException>(() => TarArchive.OpenArchive(unreadable));
}
[Fact]
public void TarArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new ForwardOnlyStream(new MemoryStream());
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() => TarArchive.OpenArchive([nonSeekable, seekable]));
}
[Fact]
public void Tar_FileName_Exactly_100_Characters()
{
@@ -262,7 +284,7 @@ public class TarArchiveTests : ArchiveTests
}
using (var inputMemory = new MemoryStream(mstm.ToArray()))
{
var tropt = new ReaderOptions { ArchiveEncoding = enc };
var tropt = ReaderOptions.ForExternalStream.WithArchiveEncoding(enc);
using (var tr = TarReader.OpenReader(inputMemory, tropt))
{
while (tr.MoveToNextEntry())
@@ -336,7 +358,7 @@ public class TarArchiveTests : ArchiveTests
using Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
using var reader = ReaderFactory.OpenReader(stream);
Assert.Equal(ArchiveType.Tar, reader.ArchiveType);
Assert.Equal(ArchiveType.Tar, reader.Type);
Assert.True(reader.MoveToNextEntry());
}
}

View File

@@ -156,7 +156,7 @@ public class TarReaderAsyncTests : ReaderTests
var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsRar.tar");
using Stream stream = File.OpenRead(archiveFullPath);
using var reader = ReaderFactory.OpenReader(stream);
Assert.True(reader.ArchiveType == ArchiveType.Tar);
Assert.True(reader.Type == ArchiveType.Tar);
}
[Fact]

View File

@@ -195,7 +195,7 @@ public class TarReaderTests : ReaderTests
var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "Tar.ContainsRar.tar");
using Stream stream = File.OpenRead(archiveFullPath);
using var reader = ReaderFactory.OpenReader(stream);
Assert.True(reader.ArchiveType == ArchiveType.Tar);
Assert.True(reader.Type == ArchiveType.Tar);
}
[Fact]

View File

@@ -224,7 +224,7 @@ public class TestBase : IAsyncDisposable
protected void CompareArchivesByPath(string file1, string file2, Encoding? encoding = null)
{
var readerOptions = new ReaderOptions { LeaveStreamOpen = false };
var readerOptions = ReaderOptions.ForExternalStream.WithLeaveStreamOpen(false);
readerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default;
//don't compare the order. OS X reads files from the file system in a different order therefore makes the archive ordering different

View File

@@ -0,0 +1,34 @@
using System;
using System.IO;
using System.Threading.Tasks;
using SharpCompress.Common;
using SharpCompress.Test.Mocks;
using SharpCompress.Writers;
using Xunit;
namespace SharpCompress.Test;
public class WriterFactoryTests
{
[Fact]
public void OpenWriter_Stream_Throws_On_Unwritable_Stream()
{
using var unwritable = new TestStream(new MemoryStream(), true, false, true);
Assert.Throws<ArgumentException>(() =>
WriterFactory.OpenWriter(unwritable, ArchiveType.Zip, WriterOptions.ForZip())
);
}
[Fact]
public async ValueTask OpenAsyncWriter_Stream_Throws_On_Unwritable_Stream()
{
using var unwritable = new TestStream(new MemoryStream(), true, false, true);
await Assert.ThrowsAsync<ArgumentException>(() =>
WriterFactory
.OpenAsyncWriter(unwritable, ArchiveType.Zip, WriterOptions.ForZip())
.AsTask()
);
}
}

View File

@@ -39,7 +39,7 @@ public class WriterTests : TestBase
using (Stream stream = File.OpenRead(Path.Combine(SCRATCH2_FILES_PATH, archive)))
{
var readerOptions = new ReaderOptions();
var readerOptions = ReaderOptions.ForExternalStream;
readerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default;
@@ -90,7 +90,7 @@ public class WriterTests : TestBase
using (Stream stream = File.OpenRead(Path.Combine(SCRATCH2_FILES_PATH, archive)))
{
var readerOptions = new ReaderOptions();
var readerOptions = ReaderOptions.ForExternalStream;
readerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default;

View File

@@ -201,7 +201,10 @@ public class Zip64AsyncTests : WriterTests
{
await using var rd = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(fs),
new ReaderOptions { LookForHeader = false }
ReaderOptions.ForExternalStream with
{
LookForHeader = false,
}
);
while (await rd.MoveToNextEntryAsync())
{

View File

@@ -182,7 +182,15 @@ public class Zip64Tests : WriterTests
long size = 0;
IEntry? prev = null;
using (var fs = File.OpenRead(filename))
using (var rd = ZipReader.OpenReader(fs, new ReaderOptions { LookForHeader = false }))
using (
var rd = ZipReader.OpenReader(
fs,
ReaderOptions.ForExternalStream with
{
LookForHeader = false,
}
)
)
{
while (rd.MoveToNextEntry())
{

View File

@@ -7,6 +7,7 @@ using SharpCompress.Archives.Zip;
using SharpCompress.Common;
using SharpCompress.Common.Zip;
using SharpCompress.Readers;
using SharpCompress.Test.Mocks;
using SharpCompress.Writers;
using SharpCompress.Writers.Zip;
using Xunit;
@@ -28,6 +29,23 @@ public class ZipArchiveTests : ArchiveTests
[Fact]
public void Zip_BZip2_ArchiveStreamRead() => ArchiveStreamRead("Zip.bzip2.zip");
[Fact]
public void ZipArchive_StreamCollection_Throws_On_NonSeekable_Stream()
{
using var nonSeekable = new NonSeekableMemoryStream();
using var seekable = new MemoryStream();
Assert.Throws<ArgumentException>(() => ZipArchive.OpenArchive([nonSeekable, seekable]));
}
[Fact]
public void ZipArchive_Stream_Throws_On_Unreadable_Stream()
{
using var unreadable = new TestStream(new MemoryStream(), false, true, true);
Assert.Throws<ArgumentException>(() => ZipArchive.OpenArchive(unreadable));
}
[Fact]
public void Zip_Deflate_Streamed2_ArchiveStreamRead() =>
ArchiveStreamRead("Zip.deflate.dd-.zip");
@@ -465,7 +483,10 @@ public class ZipArchiveTests : ArchiveTests
using (
var reader = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
)
)
{
@@ -482,7 +503,10 @@ public class ZipArchiveTests : ArchiveTests
{
using var reader = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES2.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
foreach (var entry in reader.Entries.Where(x => !x.IsDirectory))
{
@@ -499,7 +523,10 @@ public class ZipArchiveTests : ArchiveTests
// Test that WinZip AES encrypted entries correctly report their compression type
using var deflateArchive = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
foreach (var entry in deflateArchive.Entries.Where(x => !x.IsDirectory))
{
@@ -509,7 +536,10 @@ public class ZipArchiveTests : ArchiveTests
using var lzmaArchive = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.WinzipAES.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
foreach (var entry in lzmaArchive.Entries.Where(x => !x.IsDirectory))
{
@@ -523,7 +553,10 @@ public class ZipArchiveTests : ArchiveTests
{
using var archive = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.zstd.WinzipAES.mixed.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
VerifyMixedZstandardArchive(archive);
@@ -535,7 +568,13 @@ public class ZipArchiveTests : ArchiveTests
using var stream = File.OpenRead(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.zstd.WinzipAES.mixed.zip")
);
using var archive = ZipArchive.OpenArchive(stream, new ReaderOptions { Password = "test" });
using var archive = ZipArchive.OpenArchive(
stream,
ReaderOptions.ForExternalStream with
{
Password = "test",
}
);
VerifyMixedZstandardArchive(archive);
}
@@ -571,7 +610,10 @@ public class ZipArchiveTests : ArchiveTests
// Test that Pkware encrypted entries correctly report their compression type
using var deflateArchive = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.pkware.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
foreach (var entry in deflateArchive.Entries.Where(x => !x.IsDirectory))
{
@@ -581,7 +623,10 @@ public class ZipArchiveTests : ArchiveTests
using var bzip2Archive = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
foreach (var entry in bzip2Archive.Entries.Where(x => !x.IsDirectory))
{
@@ -595,7 +640,10 @@ public class ZipArchiveTests : ArchiveTests
{
using var reader = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.zip64.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
var isComplete = reader.IsComplete;
Assert.Equal(1, reader.Volumes.Count());
@@ -611,7 +659,10 @@ public class ZipArchiveTests : ArchiveTests
using (
var reader = ZipArchive.OpenArchive(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
)
)
{
@@ -673,7 +724,10 @@ public class ZipArchiveTests : ArchiveTests
using var fileStream = File.OpenRead(zipFile);
using var archive = ArchiveFactory.OpenArchive(
fileStream,
new ReaderOptions { Password = "12345678" }
ReaderOptions.ForExternalStream with
{
Password = "12345678",
}
);
var entries = archive.Entries.Where(entry => !entry.IsDirectory);
foreach (var entry in entries)
@@ -881,7 +935,7 @@ public class ZipArchiveTests : ArchiveTests
{
var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions
ReaderOptions.ForExternalStream with
{
ArchiveEncoding = new ArchiveEncoding
{
@@ -896,7 +950,7 @@ public class ZipArchiveTests : ArchiveTests
{
var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions
ReaderOptions.ForExternalStream with
{
ArchiveEncoding = new ArchiveEncoding
{

View File

@@ -143,7 +143,10 @@ public class ZipReaderAsyncTests : ReaderTests
using (
IReader baseReader = ZipReader.OpenReader(
stream,
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
@@ -169,7 +172,7 @@ public class ZipReaderAsyncTests : ReaderTests
await using (
var reader = await ReaderFactory.OpenAsyncReader(
new AsyncOnlyStream(stream),
new ReaderOptions().WithLeaveStreamOpen(false)
ReaderOptions.ForExternalStream.WithLeaveStreamOpen(false)
)
)
{
@@ -215,7 +218,10 @@ public class ZipReaderAsyncTests : ReaderTests
using (
IReader baseReader = ZipReader.OpenReader(
stream,
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
@@ -244,7 +250,10 @@ public class ZipReaderAsyncTests : ReaderTests
await using (
var reader = await ReaderFactory.OpenAsyncReader(
stream,
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
@@ -272,7 +281,10 @@ public class ZipReaderAsyncTests : ReaderTests
await using (
var reader = await ReaderFactory.OpenAsyncReader(
stream,
new ReaderOptions { Password = "test" }
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{

View File

@@ -129,7 +129,15 @@ public class ZipReaderTests : ReaderTests
using (
Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Zip.bzip2.pkware.zip"))
)
using (var reader = ZipReader.OpenReader(stream, new ReaderOptions { Password = "test" }))
using (
var reader = ZipReader.OpenReader(
stream,
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
while (reader.MoveToNextEntry())
{
@@ -152,7 +160,7 @@ public class ZipReaderTests : ReaderTests
using (
var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions().WithLeaveStreamOpen(false)
ReaderOptions.ForExternalStream.WithLeaveStreamOpen(false)
)
)
{
@@ -194,7 +202,13 @@ public class ZipReaderTests : ReaderTests
)
)
using (
var reader = ZipReader.OpenReader(stream, new ReaderOptions { Password = "test" })
var reader = ZipReader.OpenReader(
stream,
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
while (reader.MoveToNextEntry())
@@ -217,7 +231,15 @@ public class ZipReaderTests : ReaderTests
Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.WinzipAES.zip")
)
)
using (var reader = ZipReader.OpenReader(stream, new ReaderOptions { Password = "test" }))
using (
var reader = ZipReader.OpenReader(
stream,
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
while (reader.MoveToNextEntry())
{
@@ -236,7 +258,15 @@ public class ZipReaderTests : ReaderTests
{
var count = 0;
using (Stream stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "zipcrypto.zip")))
using (var reader = ZipReader.OpenReader(stream, new ReaderOptions { Password = "test" }))
using (
var reader = ZipReader.OpenReader(
stream,
ReaderOptions.ForExternalStream with
{
Password = "test",
}
)
)
{
while (reader.MoveToNextEntry())
{
@@ -402,7 +432,10 @@ public class ZipReaderTests : ReaderTests
{
using var reader = ReaderFactory.OpenReader(
Path.Combine(TEST_ARCHIVES_PATH, "Zip.none.encrypted.zip"),
new ReaderOptions { Password = "test" }
ReaderOptions.ForFilePath with
{
Password = "test",
}
);
reader.MoveToNextEntry();
Assert.Equal("first.txt", reader.Entry.Key);

View File

@@ -99,7 +99,10 @@ public class ZipShortReadTests : ReaderTests
var names = new List<string>();
using var reader = ReaderFactory.OpenReader(
stream,
new ReaderOptions { LeaveStreamOpen = true }
ReaderOptions.ForExternalStream with
{
LeaveStreamOpen = true,
}
);
while (reader.MoveToNextEntry())