clean up seekable checks

This commit is contained in:
Adam Hathcock
2026-04-23 10:19:37 +01:00
parent 2bae46e28a
commit 5d14c96fb0
14 changed files with 96 additions and 28 deletions

View File

@@ -92,15 +92,13 @@ public static partial class ArchiveFactory
)
{
cancellationToken.ThrowIfCancellationRequested();
streams.NotNull(nameof(streams));
var streamsArray = streams;
var streamsArray = streams.RequireReadable();
streamsArray.RequireSeekable();
if (streamsArray.Count == 0)
{
throw new ArchiveOperationException("No streams");
}
streamsArray.RequireSeekable();
var firstStream = streamsArray[0];
if (streamsArray.Count == 1)
{

View File

@@ -73,15 +73,13 @@ public static partial class ArchiveFactory
public static IArchive OpenArchive(IReadOnlyList<Stream> streams, ReaderOptions? options = null)
{
streams.NotNull(nameof(streams));
var streamsArray = streams;
var streamsArray = streams.RequireReadable();
streamsArray.RequireSeekable();
if (streamsArray.Count == 0)
{
throw new ArchiveOperationException("No streams");
}
streamsArray.RequireSeekable();
var firstStream = streamsArray[0];
if (streamsArray.Count == 1)
{

View File

@@ -76,9 +76,8 @@ public partial class GZipArchive
ReaderOptions? readerOptions = null
)
{
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
return new GZipArchive(
new SourceStream(
strms[0],
@@ -93,6 +92,7 @@ public partial class GZipArchive
ReaderOptions? readerOptions = null
)
{
stream.RequireReadable();
stream.RequireSeekable();
return new GZipArchive(

View File

@@ -58,6 +58,7 @@ public partial class RarArchive
public static IRarArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
{
stream.RequireReadable();
stream.RequireSeekable();
return new RarArchive(
@@ -86,9 +87,8 @@ public partial class RarArchive
ReaderOptions? readerOptions = null
)
{
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
return new RarArchive(
new SourceStream(
strms[0],

View File

@@ -71,9 +71,8 @@ public partial class SevenZipArchive
ReaderOptions? readerOptions = null
)
{
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
return new SevenZipArchive(
new SourceStream(
strms[0],
@@ -85,6 +84,7 @@ public partial class SevenZipArchive
public static IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
{
stream.RequireReadable();
stream.RequireSeekable();
return new SevenZipArchive(

View File

@@ -66,9 +66,8 @@ public partial class TarArchive
ReaderOptions? readerOptions = null
)
{
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
var sourceStream = new SourceStream(
strms[0],
i => i < strms.Count ? strms[i] : null,
@@ -87,6 +86,7 @@ public partial class TarArchive
ReaderOptions? readerOptions = null
)
{
stream.RequireReadable();
stream.RequireSeekable();
return OpenArchive([stream], readerOptions);
@@ -98,7 +98,7 @@ public partial class TarArchive
CancellationToken cancellationToken = default
)
{
stream.NotNull(nameof(stream));
stream.RequireReadable();
stream.RequireSeekable();
var sourceStream = new SourceStream(
stream,
@@ -155,9 +155,8 @@ public partial class TarArchive
)
{
cancellationToken.ThrowIfCancellationRequested();
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
var sourceStream = new SourceStream(
strms[0],
i => i < strms.Count ? strms[i] : null,

View File

@@ -67,9 +67,8 @@ public partial class ZipArchive
ReaderOptions? readerOptions = null
)
{
streams.NotNull(nameof(streams));
streams.RequireSeekable();
var strms = streams;
var strms = streams.RequireReadable();
strms.RequireSeekable();
return new ZipArchive(
new SourceStream(
strms[0],
@@ -84,6 +83,7 @@ public partial class ZipArchive
ReaderOptions? readerOptions = null
)
{
stream.RequireReadable();
stream.RequireSeekable();
return new ZipArchive(
@@ -128,7 +128,6 @@ public partial class ZipArchive
)
{
cancellationToken.ThrowIfCancellationRequested();
streams.RequireSeekable();
return new((IWritableAsyncArchive<ZipWriterOptions>)OpenArchive(streams, readerOptions));
}

View File

@@ -93,6 +93,24 @@ public class ArchiveFactoryTests : TestBase
);
}
[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)]

View File

@@ -137,6 +137,14 @@ public class GZipArchiveTests : ArchiveTests
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

@@ -131,6 +131,14 @@ public class RarArchiveTests : ArchiveTests
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");

View File

@@ -37,6 +37,14 @@ public class SevenZipArchiveTests : ArchiveTests
);
}
[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(

View File

@@ -32,6 +32,16 @@ public class TarArchiveAsyncTests : ArchiveTests
);
}
[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()
{

View File

@@ -34,6 +34,19 @@ 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()
{

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;
@@ -37,6 +38,14 @@ public class ZipArchiveTests : ArchiveTests
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");