mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-07-08 18:16:30 +00:00
Merge pull request #1297 from adamhathcock/adam/enforce-seekable
Enforce seekable, readable and writable on streams
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,3 +24,4 @@ profiler-snapshots/
|
||||
.DS_Store
|
||||
*.snupkg
|
||||
benchmark-results/
|
||||
/.opencode
|
||||
|
||||
@@ -92,13 +92,7 @@ public static partial class ArchiveFactory
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
streams.NotNull(nameof(streams));
|
||||
var streamsArray = streams;
|
||||
if (streamsArray.Count == 0)
|
||||
{
|
||||
throw new ArchiveOperationException("No streams");
|
||||
}
|
||||
|
||||
var streamsArray = streams.RequireReadable().RequireSeekable().ToList();
|
||||
var firstStream = streamsArray[0];
|
||||
if (streamsArray.Count == 1)
|
||||
{
|
||||
@@ -143,11 +137,8 @@ public static partial class ArchiveFactory
|
||||
)
|
||||
where T : IFactory
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
if (!stream.CanRead || !stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Stream should be readable and seekable");
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
var factories = Factory.Factories.OfType<T>();
|
||||
|
||||
|
||||
@@ -73,8 +73,7 @@ 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().RequireSeekable().ToList();
|
||||
if (streamsArray.Count == 0)
|
||||
{
|
||||
throw new ArchiveOperationException("No streams");
|
||||
@@ -121,11 +120,8 @@ public static partial class ArchiveFactory
|
||||
public static T FindFactory<T>(Stream stream)
|
||||
where T : IFactory
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
if (!stream.CanRead || !stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Stream should be readable and seekable");
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
var factories = Factory.Factories.OfType<T>();
|
||||
|
||||
@@ -160,12 +156,8 @@ public static partial class ArchiveFactory
|
||||
public static bool IsArchive(Stream stream, out ArchiveType? type)
|
||||
{
|
||||
type = null;
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (!stream.CanRead || !stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Stream should be readable and seekable");
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
var startPosition = stream.Position;
|
||||
|
||||
@@ -199,12 +191,8 @@ public static partial class ArchiveFactory
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (!stream.CanRead || !stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Stream should be readable and seekable");
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
var startPosition = stream.Position;
|
||||
|
||||
|
||||
@@ -76,8 +76,7 @@ public partial class GZipArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
return new GZipArchive(
|
||||
new SourceStream(
|
||||
strms[0],
|
||||
@@ -92,12 +91,8 @@ public partial class GZipArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (stream is not { CanSeek: true })
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
return new GZipArchive(
|
||||
new SourceStream(stream, _ => null, readerOptions ?? ReaderOptions.ForExternalStream)
|
||||
|
||||
@@ -58,12 +58,8 @@ public partial class RarArchive
|
||||
|
||||
public static IRarArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (stream is not { CanSeek: true })
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
return new RarArchive(
|
||||
new SourceStream(stream, _ => null, readerOptions ?? ReaderOptions.ForExternalStream)
|
||||
@@ -91,8 +87,7 @@ public partial class RarArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
return new RarArchive(
|
||||
new SourceStream(
|
||||
strms[0],
|
||||
|
||||
@@ -71,8 +71,7 @@ public partial class SevenZipArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
return new SevenZipArchive(
|
||||
new SourceStream(
|
||||
strms[0],
|
||||
@@ -84,12 +83,8 @@ public partial class SevenZipArchive
|
||||
|
||||
public static IArchive OpenArchive(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (stream is not { CanSeek: true })
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
return new SevenZipArchive(
|
||||
new SourceStream(stream, _ => null, readerOptions ?? ReaderOptions.ForExternalStream)
|
||||
|
||||
@@ -66,8 +66,7 @@ public partial class TarArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
var sourceStream = new SourceStream(
|
||||
strms[0],
|
||||
i => i < strms.Count ? strms[i] : null,
|
||||
@@ -86,12 +85,8 @@ public partial class TarArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (stream is not { CanSeek: true })
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
return OpenArchive([stream], readerOptions);
|
||||
}
|
||||
@@ -102,7 +97,8 @@ public partial class TarArchive
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
var sourceStream = new SourceStream(
|
||||
stream,
|
||||
i => null,
|
||||
@@ -158,8 +154,7 @@ public partial class TarArchive
|
||||
)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
var sourceStream = new SourceStream(
|
||||
strms[0],
|
||||
i => i < strms.Count ? strms[i] : null,
|
||||
|
||||
@@ -67,8 +67,7 @@ public partial class ZipArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
var strms = streams;
|
||||
var strms = streams.RequireReadable().RequireSeekable().ToList();
|
||||
return new ZipArchive(
|
||||
new SourceStream(
|
||||
strms[0],
|
||||
@@ -83,12 +82,8 @@ public partial class ZipArchive
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (stream is not { CanSeek: true })
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
stream.RequireReadable();
|
||||
stream.RequireSeekable();
|
||||
|
||||
return new ZipArchive(
|
||||
new SourceStream(stream, i => null, readerOptions ?? ReaderOptions.ForExternalStream)
|
||||
|
||||
@@ -19,7 +19,7 @@ public partial class AceReader
|
||||
/// <returns>An AceReader instance.</returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new SingleVolumeAceReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ public partial class AceReader
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeAceReader(streams, options ?? ReaderOptions.ForExternalStream);
|
||||
var streamArray = streams.RequireReadable();
|
||||
return new MultiVolumeAceReader(streamArray, options ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
public static ValueTask<IAsyncReader> OpenAsyncReader(
|
||||
@@ -61,8 +61,8 @@ public partial class AceReader
|
||||
ReaderOptions? options = null
|
||||
)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeAceReader(streams, options ?? ReaderOptions.ForExternalStream);
|
||||
var streamArray = streams.RequireReadable();
|
||||
return new MultiVolumeAceReader(streamArray, options ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
public static ValueTask<IAsyncReader> OpenAsyncReader(
|
||||
|
||||
@@ -12,7 +12,7 @@ internal class SingleVolumeAceReader : AceReader
|
||||
internal SingleVolumeAceReader(Stream stream, ReaderOptions options)
|
||||
: base(options)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ public partial class ArcReader : AbstractReader<ArcEntry, ArcVolume>
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new ArcReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract partial class ArjReader : AbstractReader<ArjEntry, ArjVolume>
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new SingleVolumeArjReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ public abstract partial class ArjReader : AbstractReader<ArjEntry, ArjVolume>
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeArjReader(streams, options ?? ReaderOptions.ForExternalStream);
|
||||
var streamArray = streams.RequireReadable();
|
||||
return new MultiVolumeArjReader(streamArray, options ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
protected abstract void ValidateArchive(ArjVolume archive);
|
||||
|
||||
@@ -12,7 +12,7 @@ internal class SingleVolumeArjReader : ArjReader
|
||||
internal SingleVolumeArjReader(Stream stream, ReaderOptions options)
|
||||
: base(options)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
_stream = stream;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public partial class GZipReader
|
||||
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new GZipReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public partial class LzwReader
|
||||
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new LzwReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public abstract partial class RarReader : AbstractReader<RarReaderEntry, RarVolu
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new SingleVolumeRarReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ public abstract partial class RarReader : AbstractReader<RarReaderEntry, RarVolu
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(IEnumerable<Stream> streams, ReaderOptions? options = null)
|
||||
{
|
||||
streams.NotNull(nameof(streams));
|
||||
return new MultiVolumeRarReader(streams, options ?? ReaderOptions.ForExternalStream);
|
||||
var streamArray = streams.RequireReadable();
|
||||
return new MultiVolumeRarReader(streamArray, options ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
protected override IEnumerable<RarReaderEntry> GetEntries(Stream stream)
|
||||
|
||||
@@ -56,7 +56,7 @@ public static partial class ReaderFactory
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
options ??= ReaderOptions.ForExternalStream;
|
||||
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
|
||||
@@ -29,7 +29,7 @@ public static partial class ReaderFactory
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? options = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
options ??= ReaderOptions.ForExternalStream;
|
||||
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
|
||||
@@ -170,7 +170,7 @@ public partial class TarReader
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
readerOptions ??= ReaderOptions.ForExternalStream;
|
||||
var sharpCompressStream = SharpCompressStream.Create(
|
||||
stream,
|
||||
|
||||
@@ -47,7 +47,7 @@ public partial class ZipReader : AbstractReader<ZipEntry, ZipVolume>
|
||||
/// <returns></returns>
|
||||
public static IReader OpenReader(Stream stream, ReaderOptions? readerOptions = null)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new ZipReader(stream, readerOptions ?? ReaderOptions.ForExternalStream);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public partial class ZipReader : AbstractReader<ZipEntry, ZipVolume>
|
||||
IEnumerable<ZipEntry> entries
|
||||
)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireReadable();
|
||||
return new ZipReader(stream, options ?? ReaderOptions.ForExternalStream, entries);
|
||||
}
|
||||
|
||||
|
||||
56
src/SharpCompress/StreamValidationExtensions.cs
Normal file
56
src/SharpCompress/StreamValidationExtensions.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace SharpCompress;
|
||||
|
||||
internal static class StreamValidationExtensions
|
||||
{
|
||||
internal static void RequireReadable(this Stream stream)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (!stream.CanRead)
|
||||
{
|
||||
throw new ArgumentException("Stream must be readable", nameof(stream));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RequireSeekable(this Stream stream)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (!stream.CanSeek)
|
||||
{
|
||||
throw new ArgumentException("Stream must be seekable", nameof(stream));
|
||||
}
|
||||
}
|
||||
|
||||
internal static void RequireWritable(this Stream stream)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
|
||||
if (!stream.CanWrite)
|
||||
{
|
||||
throw new ArgumentException("Stream must be writable", nameof(stream));
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<Stream> RequireSeekable(this IEnumerable<Stream> streams)
|
||||
{
|
||||
foreach (var stream in streams)
|
||||
{
|
||||
stream.RequireSeekable();
|
||||
yield return stream;
|
||||
}
|
||||
}
|
||||
|
||||
internal static IEnumerable<Stream> RequireReadable(this IEnumerable<Stream> streams)
|
||||
{
|
||||
foreach (var stream in streams)
|
||||
{
|
||||
stream.RequireReadable();
|
||||
yield return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ public partial class GZipWriter : IWriterOpenable<GZipWriterOptions>
|
||||
|
||||
public static IWriter OpenWriter(Stream stream, GZipWriterOptions writerOptions)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireWritable();
|
||||
return new GZipWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public partial class SevenZipWriter : IWriterOpenable<SevenZipWriterOptions>
|
||||
/// </summary>
|
||||
public static IWriter OpenWriter(Stream stream, SevenZipWriterOptions writerOptions)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireWritable();
|
||||
return new SevenZipWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ public partial class TarWriter : IWriterOpenable<TarWriterOptions>
|
||||
|
||||
public static IWriter OpenWriter(Stream stream, TarWriterOptions writerOptions)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireWritable();
|
||||
return new TarWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ public static class WriterFactory
|
||||
IWriterOptions writerOptions
|
||||
)
|
||||
{
|
||||
stream.RequireWritable();
|
||||
|
||||
var factory = Factories
|
||||
.Factory.Factories.OfType<IWriterFactory>()
|
||||
.FirstOrDefault(item => item.KnownArchiveType == archiveType);
|
||||
@@ -102,6 +104,8 @@ public static class WriterFactory
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
{
|
||||
stream.RequireWritable();
|
||||
|
||||
var factory = Factories
|
||||
.Factory.Factories.OfType<IWriterFactory>()
|
||||
.FirstOrDefault(item => item.KnownArchiveType == archiveType);
|
||||
|
||||
@@ -22,7 +22,7 @@ public partial class ZipWriter : IWriterOpenable<ZipWriterOptions>
|
||||
|
||||
public static IWriter OpenWriter(Stream stream, ZipWriterOptions writerOptions)
|
||||
{
|
||||
stream.NotNull(nameof(stream));
|
||||
stream.RequireWritable();
|
||||
return new ZipWriter(stream, writerOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -268,9 +268,9 @@
|
||||
"net10.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.0, )",
|
||||
"resolved": "10.0.0",
|
||||
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
|
||||
"requested": "[10.0.6, )",
|
||||
"resolved": "10.0.6",
|
||||
"contentHash": "QKuvS0LWX4fjFqeDkyM7Kqt8P3wYTiPD4nwU+9y59n0sCiG714fxDgbbN82vDnzq89AF/PiHl92TP2C4aFDUQA=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
@@ -400,9 +400,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.22, )",
|
||||
"resolved": "8.0.22",
|
||||
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
|
||||
"requested": "[8.0.26, )",
|
||||
"resolved": "8.0.26",
|
||||
"contentHash": "o7/yVssM2r9Wyln2s9edBd5ANZXqdSdBI+g7JqXkyJmXrhs2WsJp25K5yPnYrTgdKBCjKB8bg+O2oew4sgzFaA=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Factories;
|
||||
using SharpCompress.Test.Mocks;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test;
|
||||
@@ -61,6 +63,26 @@ public class ArchiveFactoryTests : TestBase
|
||||
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()
|
||||
{
|
||||
@@ -71,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)]
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -122,6 +122,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");
|
||||
|
||||
|
||||
41
tests/SharpCompress.Test/ReaderFactoryTests.cs
Normal file
41
tests/SharpCompress.Test/ReaderFactoryTests.cs
Normal 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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,6 +26,25 @@ 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(
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
34
tests/SharpCompress.Test/WriterFactoryTests.cs
Normal file
34
tests/SharpCompress.Test/WriterFactoryTests.cs
Normal 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()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user