diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 00b1a064..393d1879 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,10 +3,11 @@
"isRoot": true,
"tools": {
"csharpier": {
- "version": "0.28.1",
+ "version": "0.30.6",
"commands": [
"dotnet-csharpier"
- ]
+ ],
+ "rollForward": false
}
}
}
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 6bc10b2c..1108acd8 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -1,17 +1,19 @@
-
+
-
-
+
+
-
+
+
-
-
-
-
+
+
+
+
+
diff --git a/FORMATS.md b/FORMATS.md
index cca190ad..eb27ad2f 100644
--- a/FORMATS.md
+++ b/FORMATS.md
@@ -11,7 +11,7 @@
| Archive Format | Compression Format(s) | Compress/Decompress | Archive API | Reader API | Writer API |
| ---------------------- | ------------------------------------------------- | ------------------- | --------------- | ---------- | ------------- |
| Rar | Rar | Decompress (1) | RarArchive | RarReader | N/A |
-| Zip (2) | None, DEFLATE, Deflate64, BZip2, LZMA/LZMA2, PPMd | Both | ZipArchive | ZipReader | ZipWriter |
+| Zip (2) | None, Shrink, Reduce, Implode, DEFLATE, Deflate64, BZip2, LZMA/LZMA2, PPMd | Both | ZipArchive | ZipReader | ZipWriter |
| Tar | None | Both | TarArchive | TarReader | TarWriter (3) |
| Tar.GZip | DEFLATE | Both | TarArchive | TarReader | TarWriter (3) |
| Tar.BZip2 | BZip2 | Both | TarArchive | TarReader | TarWriter (3) |
diff --git a/SharpCompress.sln b/SharpCompress.sln
index ab4995b1..a86d1652 100644
--- a/SharpCompress.sln
+++ b/SharpCompress.sln
@@ -20,6 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Config", "Config", "{CDB425
.editorconfig = .editorconfig
Directory.Packages.props = Directory.Packages.props
NuGet.config = NuGet.config
+ .github\workflows\dotnetcore.yml = .github\workflows\dotnetcore.yml
EndProjectSection
EndProject
Global
diff --git a/USAGE.md b/USAGE.md
index c96f9c1b..51b93774 100644
--- a/USAGE.md
+++ b/USAGE.md
@@ -27,7 +27,7 @@ To deal with the "correct" rules as well as the expectations of users, I've deci
To be explicit though, consider always using the overloads that use `ReaderOptions` or `WriterOptions` and explicitly set `LeaveStreamOpen` the way you want.
-If using Compression Stream classes directly and you don't want the wrapped stream to be closed. Use the `NonDisposingStream` as a wrapped to prevent the stream being disposed. The change in 0.21 simplified a lot even though the usage is a bit more convoluted.
+If using Compression Stream classes directly and you don't want the wrapped stream to be closed. Use the `NonDisposingStream` as a wrapper to prevent the stream being disposed. The change in 0.21 simplified a lot even though the usage is a bit more convoluted.
## Samples
diff --git a/build/Program.cs b/build/Program.cs
index acafec41..39acd0c0 100644
--- a/build/Program.cs
+++ b/build/Program.cs
@@ -61,7 +61,7 @@ Target(
Target(
Test,
DependsOn(Build),
- ForEach("net8.0", "net462"),
+ ForEach("net8.0", "net48"),
framework =>
{
IEnumerable GetFiles(string d)
@@ -69,7 +69,7 @@ Target(
return Glob.Files(".", d);
}
- if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net462")
+ if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && framework == "net48")
{
return;
}
diff --git a/build/build.csproj b/build/build.csproj
index 8e837d3a..e0dffc7f 100644
--- a/build/build.csproj
+++ b/build/build.csproj
@@ -2,7 +2,7 @@
Exe
- net7.0
+ net8.0
diff --git a/build/packages.lock.json b/build/packages.lock.json
index 52565140..08406fdc 100644
--- a/build/packages.lock.json
+++ b/build/packages.lock.json
@@ -1,7 +1,7 @@
{
- "version": 1,
+ "version": 2,
"dependencies": {
- "net7.0": {
+ "net8.0": {
"Bullseye": {
"type": "Direct",
"requested": "[5.0.0, )",
@@ -14,11 +14,31 @@
"resolved": "1.1.9",
"contentHash": "AfK5+ECWYTP7G3AAdnU8IfVj+QpGjrh9GC2mpdcJzCvtQ4pnerAGwHsxJ9D4/RnhDUz2DSzd951O/lQjQby2Sw=="
},
+ "Microsoft.SourceLink.GitHub": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "8.0.0",
+ "Microsoft.SourceLink.Common": "8.0.0"
+ }
+ },
"SimpleExec": {
"type": "Direct",
"requested": "[12.0.0, )",
"resolved": "12.0.0",
"contentHash": "ptxlWtxC8vM6Y6e3h9ZTxBBkOWnWrm/Sa1HT+2i1xcXY3Hx2hmKDZP5RShPf8Xr9D+ivlrXNy57ktzyH8kyt+Q=="
+ },
+ "Microsoft.Build.Tasks.Git": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
+ },
+ "Microsoft.SourceLink.Common": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
}
}
}
diff --git a/src/SharpCompress/Algorithms/Adler32.cs b/src/SharpCompress/Algorithms/Adler32.cs
index 10dbfc4d..f7ea0eb3 100644
--- a/src/SharpCompress/Algorithms/Adler32.cs
+++ b/src/SharpCompress/Algorithms/Adler32.cs
@@ -141,7 +141,7 @@ internal static class Adler32 // From https://github.com/SixLabors/ImageSharp/bl
4,
3,
2,
- 1 // tap2
+ 1, // tap2
};
#endif
diff --git a/src/SharpCompress/Archives/ArchiveFactory.cs b/src/SharpCompress/Archives/ArchiveFactory.cs
index 3f479327..b81e2c0e 100644
--- a/src/SharpCompress/Archives/ArchiveFactory.cs
+++ b/src/SharpCompress/Archives/ArchiveFactory.cs
@@ -189,9 +189,10 @@ public static class ArchiveFactory
foreach (var factory in Factory.Factories)
{
+ var isArchive = factory.IsArchive(stream);
stream.Position = startPosition;
- if (factory.IsArchive(stream, null))
+ if (isArchive)
{
type = factory.KnownArchiveType;
return true;
@@ -239,4 +240,6 @@ public static class ArchiveFactory
}
}
}
+
+ public static IArchiveFactory AutoFactory { get; } = new AutoArchiveFactory();
}
diff --git a/src/SharpCompress/Archives/AutoArchiveFactory.cs b/src/SharpCompress/Archives/AutoArchiveFactory.cs
new file mode 100644
index 00000000..14038ea1
--- /dev/null
+++ b/src/SharpCompress/Archives/AutoArchiveFactory.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using SharpCompress.Common;
+using SharpCompress.Readers;
+
+namespace SharpCompress.Archives;
+
+class AutoArchiveFactory : IArchiveFactory
+{
+ public string Name => nameof(AutoArchiveFactory);
+
+ public ArchiveType? KnownArchiveType => null;
+
+ public IEnumerable GetSupportedExtensions() => throw new NotSupportedException();
+
+ public bool IsArchive(Stream stream, string? password = null) =>
+ throw new NotSupportedException();
+
+ public FileInfo? GetFilePart(int index, FileInfo part1) => throw new NotSupportedException();
+
+ public IArchive Open(Stream stream, ReaderOptions? readerOptions = null) =>
+ ArchiveFactory.Open(stream, readerOptions);
+
+ public IArchive Open(FileInfo fileInfo, ReaderOptions? readerOptions = null) =>
+ ArchiveFactory.Open(fileInfo, readerOptions);
+}
diff --git a/src/SharpCompress/Archives/GZip/GZipArchive.cs b/src/SharpCompress/Archives/GZip/GZipArchive.cs
index 7a33a10a..58f98ab9 100644
--- a/src/SharpCompress/Archives/GZip/GZipArchive.cs
+++ b/src/SharpCompress/Archives/GZip/GZipArchive.cs
@@ -101,7 +101,7 @@ public class GZipArchive : AbstractWritableArchive
///
///
private GZipArchive(SourceStream sourceStream)
- : base(ArchiveType.Tar, sourceStream) { }
+ : base(ArchiveType.GZip, sourceStream) { }
protected override IEnumerable LoadVolumes(SourceStream sourceStream)
{
diff --git a/src/SharpCompress/Archives/IArchiveExtensions.cs b/src/SharpCompress/Archives/IArchiveExtensions.cs
index 382c3ddf..4cba5463 100644
--- a/src/SharpCompress/Archives/IArchiveExtensions.cs
+++ b/src/SharpCompress/Archives/IArchiveExtensions.cs
@@ -54,14 +54,26 @@ public static class IArchiveExtensions
var entry = entries.Entry;
if (entry.IsDirectory)
{
+ var dirPath = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
+ if (
+ Path.GetDirectoryName(dirPath + "/") is { } emptyDirectory
+ && seenDirectories.Add(dirPath)
+ )
+ {
+ Directory.CreateDirectory(emptyDirectory);
+ }
continue;
}
- // Create each directory
+ // Create each directory if not already created
var path = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
- if (Path.GetDirectoryName(path) is { } directory && seenDirectories.Add(path))
+ if (Path.GetDirectoryName(path) is { } directory)
{
- Directory.CreateDirectory(directory);
+ if (!Directory.Exists(directory) && !seenDirectories.Contains(directory))
+ {
+ Directory.CreateDirectory(directory);
+ seenDirectories.Add(directory);
+ }
}
// Write file
diff --git a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
index 6d9b44fd..65f31d01 100644
--- a/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
+++ b/src/SharpCompress/Archives/Rar/FileInfoRarArchiveVolume.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using SharpCompress.Common.Rar;
diff --git a/src/SharpCompress/Archives/Rar/RarArchive.cs b/src/SharpCompress/Archives/Rar/RarArchive.cs
index a05ad417..6a5c9781 100644
--- a/src/SharpCompress/Archives/Rar/RarArchive.cs
+++ b/src/SharpCompress/Archives/Rar/RarArchive.cs
@@ -14,6 +14,7 @@ namespace SharpCompress.Archives.Rar;
public class RarArchive : AbstractArchive
{
+ private bool _disposed;
internal Lazy UnpackV2017 { get; } =
new(() => new Compressors.Rar.UnpackV2017.Unpack());
internal Lazy UnpackV1 { get; } = new(() => new Compressors.Rar.UnpackV1.Unpack());
@@ -25,6 +26,20 @@ public class RarArchive : AbstractArchive
private RarArchive(SourceStream sourceStream)
: base(ArchiveType.Rar, sourceStream) { }
+ public override void Dispose()
+ {
+ if (!_disposed)
+ {
+ if (UnpackV1.IsValueCreated && UnpackV1.Value is IDisposable unpackV1)
+ {
+ unpackV1.Dispose();
+ }
+
+ _disposed = true;
+ base.Dispose();
+ }
+ }
+
protected override IEnumerable LoadEntries(IEnumerable volumes) =>
RarArchiveEntryFactory.GetEntries(this, volumes, ReaderOptions);
diff --git a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
index ee165982..88a85e96 100644
--- a/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
+++ b/src/SharpCompress/Archives/SevenZip/SevenZipArchive.cs
@@ -163,7 +163,7 @@ public class SevenZipArchive : AbstractArchive
);
}
}
+ else
+ {
+ throw new IncompleteArchiveException("Failed to read TAR header");
+ }
}
}
diff --git a/src/SharpCompress/AssemblyInfo.cs b/src/SharpCompress/AssemblyInfo.cs
index 0270020d..e51d97fe 100644
--- a/src/SharpCompress/AssemblyInfo.cs
+++ b/src/SharpCompress/AssemblyInfo.cs
@@ -1,3 +1,7 @@
using System;
+using System.Runtime.CompilerServices;
[assembly: CLSCompliant(true)]
+[assembly: InternalsVisibleTo(
+ "SharpCompress.Test,PublicKey=0024000004800000940000000602000000240000525341310004000001000100158bebf1433f76dffc356733c138babea7a47536c65ed8009b16372c6f4edbb20554db74a62687f56b97c20a6ce8c4b123280279e33c894e7b3aa93ab3c573656fde4db576cfe07dba09619ead26375b25d2c4a8e43f7be257d712b0dd2eb546f67adb09281338618a58ac834fc038dd7e2740a7ab3591826252e4f4516306dc"
+)]
diff --git a/src/SharpCompress/BufferPool.cs b/src/SharpCompress/BufferPool.cs
deleted file mode 100644
index b11dbe6f..00000000
--- a/src/SharpCompress/BufferPool.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System.Buffers;
-
-namespace SharpCompress;
-
-internal static class BufferPool
-{
- ///
- /// gets a buffer from the pool
- ///
- /// size of the buffer
- /// the buffer
- public static byte[] Rent(int bufferSize)
- {
-#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
- return ArrayPool.Shared.Rent(bufferSize);
-#else
- return new byte[bufferSize];
-#endif
- }
-
- ///
- /// returns a buffer to the pool
- ///
- /// the buffer to return
- public static void Return(byte[] buffer)
- {
-#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
- ArrayPool.Shared.Return(buffer);
-#else
- // no-op
-#endif
- }
-}
diff --git a/src/SharpCompress/Common/ArchiveType.cs b/src/SharpCompress/Common/ArchiveType.cs
index 49b35387..f9c7db09 100644
--- a/src/SharpCompress/Common/ArchiveType.cs
+++ b/src/SharpCompress/Common/ArchiveType.cs
@@ -6,5 +6,5 @@ public enum ArchiveType
Zip,
Tar,
SevenZip,
- GZip
+ GZip,
}
diff --git a/src/SharpCompress/Common/CompressionType.cs b/src/SharpCompress/Common/CompressionType.cs
index 20f166c4..45b6aeeb 100644
--- a/src/SharpCompress/Common/CompressionType.cs
+++ b/src/SharpCompress/Common/CompressionType.cs
@@ -16,5 +16,10 @@ public enum CompressionType
Unknown,
Deflate64,
Shrink,
- Lzw
+ Lzw,
+ Reduce1,
+ Reduce2,
+ Reduce3,
+ Reduce4,
+ Explode,
}
diff --git a/src/SharpCompress/Common/ExtractionMethods.cs b/src/SharpCompress/Common/ExtractionMethods.cs
index 27d41648..799d47b3 100644
--- a/src/SharpCompress/Common/ExtractionMethods.cs
+++ b/src/SharpCompress/Common/ExtractionMethods.cs
@@ -37,6 +37,7 @@ internal static class ExtractionMethods
options ??= new ExtractionOptions() { Overwrite = true };
var file = Path.GetFileName(entry.Key.NotNull("Entry Key is null")).NotNull("File is null");
+ file = Utility.ReplaceInvalidFileNameChars(file);
if (options.ExtractFullPath)
{
var folder = Path.GetDirectoryName(entry.Key.NotNull("Entry Key is null"))
diff --git a/src/SharpCompress/Common/Rar/Headers/Flags.cs b/src/SharpCompress/Common/Rar/Headers/Flags.cs
index 990dbc99..ef654ad5 100644
--- a/src/SharpCompress/Common/Rar/Headers/Flags.cs
+++ b/src/SharpCompress/Common/Rar/Headers/Flags.cs
@@ -13,7 +13,7 @@ public enum HeaderType : byte
Sign,
NewSub,
EndArchive,
- Crypt
+ Crypt,
}
internal static class HeaderCodeV
diff --git a/src/SharpCompress/Common/Rar/RarVolume.cs b/src/SharpCompress/Common/Rar/RarVolume.cs
index 274ac0a2..d05e16c2 100644
--- a/src/SharpCompress/Common/Rar/RarVolume.cs
+++ b/src/SharpCompress/Common/Rar/RarVolume.cs
@@ -61,9 +61,8 @@ public abstract class RarVolume : Volume
var fh = (FileHeader)header;
if (fh.FileName == "CMT")
{
- var part = CreateFilePart(lastMarkHeader!, fh);
var buffer = new byte[fh.CompressedSize];
- part.GetCompressedStream().NotNull().Read(buffer, 0, buffer.Length);
+ fh.PackedStream.Read(buffer, 0, buffer.Length);
Comment = Encoding.UTF8.GetString(buffer, 0, buffer.Length - 1);
}
}
diff --git a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
index 96488124..f280d64a 100644
--- a/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
+++ b/src/SharpCompress/Common/SevenZip/ArchiveReader.cs
@@ -1220,23 +1220,46 @@ internal class ArchiveReader
#region Public Methods
- public void Open(Stream stream)
+ public void Open(Stream stream, bool lookForHeader)
{
Close();
_streamOrigin = stream.Position;
_streamEnding = stream.Length;
- // TODO: Check Signature!
- _header = new byte[0x20];
- for (var offset = 0; offset < 0x20; )
+ var canScan = lookForHeader ? 0x80000 - 20 : 0;
+ while (true)
{
- var delta = stream.Read(_header, offset, 0x20 - offset);
- if (delta == 0)
+ // TODO: Check Signature!
+ _header = new byte[0x20];
+ for (var offset = 0; offset < 0x20; )
{
- throw new EndOfStreamException();
+ var delta = stream.Read(_header, offset, 0x20 - offset);
+ if (delta == 0)
+ {
+ throw new EndOfStreamException();
+ }
+
+ offset += delta;
}
- offset += delta;
+
+ if (
+ !lookForHeader
+ || _header
+ .AsSpan(0, length: 6)
+ .SequenceEqual([0x37, 0x7A, 0xBC, 0xAF, 0x27, 0x1C])
+ )
+ {
+ break;
+ }
+
+ if (canScan == 0)
+ {
+ throw new InvalidFormatException("Unable to find 7z signature");
+ }
+
+ canScan--;
+ stream.Position = ++_streamOrigin;
}
_stream = stream;
diff --git a/src/SharpCompress/Common/Tar/Headers/EntryType.cs b/src/SharpCompress/Common/Tar/Headers/EntryType.cs
index 3e6877c7..2dc4dbd1 100644
--- a/src/SharpCompress/Common/Tar/Headers/EntryType.cs
+++ b/src/SharpCompress/Common/Tar/Headers/EntryType.cs
@@ -14,5 +14,5 @@ internal enum EntryType : byte
LongName = (byte)'L',
SparseFile = (byte)'S',
VolumeHeader = (byte)'V',
- GlobalExtendedHeader = (byte)'g'
+ GlobalExtendedHeader = (byte)'g',
}
diff --git a/src/SharpCompress/Common/Tar/Headers/TarHeader.cs b/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
index 8f87a028..1a04740f 100644
--- a/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
+++ b/src/SharpCompress/Common/Tar/Headers/TarHeader.cs
@@ -101,57 +101,85 @@ internal sealed class TarHeader
internal bool Read(BinaryReader reader)
{
- var buffer = ReadBlock(reader);
- if (buffer.Length == 0)
+ string? longName = null;
+ string? longLinkName = null;
+ var hasLongValue = true;
+ byte[] buffer;
+ EntryType entryType;
+
+ do
+ {
+ buffer = ReadBlock(reader);
+
+ if (buffer.Length == 0)
+ {
+ return false;
+ }
+
+ entryType = ReadEntryType(buffer);
+
+ // LongName and LongLink headers can follow each other and need
+ // to apply to the header that follows them.
+ if (entryType == EntryType.LongName)
+ {
+ longName = ReadLongName(reader, buffer);
+ continue;
+ }
+ else if (entryType == EntryType.LongLink)
+ {
+ longLinkName = ReadLongName(reader, buffer);
+ continue;
+ }
+
+ hasLongValue = false;
+ } while (hasLongValue);
+
+ // Check header checksum
+ if (!checkChecksum(buffer))
{
return false;
}
- // for symlinks, additionally read the linkname
- if (ReadEntryType(buffer) == EntryType.SymLink)
- {
- LinkName = ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
- }
-
- if (ReadEntryType(buffer) == EntryType.LongName)
- {
- Name = ReadLongName(reader, buffer);
- buffer = ReadBlock(reader);
- }
- else
- {
- Name = ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
- }
-
- EntryType = ReadEntryType(buffer);
+ Name = longName ?? ArchiveEncoding.Decode(buffer, 0, 100).TrimNulls();
+ EntryType = entryType;
Size = ReadSize(buffer);
+ // for symlinks, additionally read the linkname
+ if (entryType == EntryType.SymLink || entryType == EntryType.HardLink)
+ {
+ LinkName = longLinkName ?? ArchiveEncoding.Decode(buffer, 157, 100).TrimNulls();
+ }
+
Mode = ReadAsciiInt64Base8(buffer, 100, 7);
- if (EntryType == EntryType.Directory)
+
+ if (entryType == EntryType.Directory)
{
Mode |= 0b1_000_000_000;
}
UserId = ReadAsciiInt64Base8oldGnu(buffer, 108, 7);
GroupId = ReadAsciiInt64Base8oldGnu(buffer, 116, 7);
- var unixTimeStamp = ReadAsciiInt64Base8(buffer, 136, 11);
- LastModifiedTime = EPOCH.AddSeconds(unixTimeStamp).ToLocalTime();
+ var unixTimeStamp = ReadAsciiInt64Base8(buffer, 136, 11);
+
+ LastModifiedTime = EPOCH.AddSeconds(unixTimeStamp).ToLocalTime();
Magic = ArchiveEncoding.Decode(buffer, 257, 6).TrimNulls();
if (!string.IsNullOrEmpty(Magic) && "ustar".Equals(Magic))
{
- var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157);
- namePrefix = namePrefix.TrimNulls();
+ var namePrefix = ArchiveEncoding.Decode(buffer, 345, 157).TrimNulls();
+
if (!string.IsNullOrEmpty(namePrefix))
{
Name = namePrefix + "/" + Name;
}
}
- if (EntryType != EntryType.LongName && Name.Length == 0)
+
+ if (entryType != EntryType.LongName && Name.Length == 0)
{
return false;
}
+
return true;
}
@@ -286,9 +314,45 @@ internal sealed class TarHeader
(byte)' ',
(byte)' ',
(byte)' ',
- (byte)' '
+ (byte)' ',
};
+ internal static bool checkChecksum(byte[] buf)
+ {
+ const int eightSpacesChksum = 256;
+ var buffer = new Span(buf).Slice(0, 512);
+ int posix_sum = eightSpacesChksum;
+ int sun_sum = eightSpacesChksum;
+
+ foreach (byte b in buffer)
+ {
+ posix_sum += b;
+ sun_sum += unchecked((sbyte)b);
+ }
+
+ // Special case, empty file header
+ if (posix_sum == eightSpacesChksum)
+ {
+ return true;
+ }
+
+ // Remove current checksum from calculation
+ foreach (byte b in buffer.Slice(148, 8))
+ {
+ posix_sum -= b;
+ sun_sum -= unchecked((sbyte)b);
+ }
+
+ // Read and compare checksum for header
+ var crc = ReadAsciiInt64Base8(buf, 148, 7);
+ if (crc != posix_sum && crc != sun_sum)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
internal static int RecalculateChecksum(byte[] buf)
{
// Set default value for checksum. That is 8 spaces.
diff --git a/src/SharpCompress/Common/Zip/Headers/HeaderFlags.cs b/src/SharpCompress/Common/Zip/Headers/HeaderFlags.cs
index 5aef3394..728f56b4 100644
--- a/src/SharpCompress/Common/Zip/Headers/HeaderFlags.cs
+++ b/src/SharpCompress/Common/Zip/Headers/HeaderFlags.cs
@@ -13,5 +13,5 @@ internal enum HeaderFlags : ushort
EnhancedDeflate = 16,
//Bit 11: Language encoding flag
- Efs = 2048
+ Efs = 2048,
}
diff --git a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
index 88e4a187..daedd9a6 100644
--- a/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
+++ b/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs
@@ -14,7 +14,7 @@ internal enum ExtraDataType : ushort
// -Info-ZIP Unicode Path Extra Field
UnicodePathExtraField = 0x7075,
Zip64ExtendedInformationExtraField = 0x0001,
- UnixTimeExtraField = 0x5455
+ UnixTimeExtraField = 0x5455,
}
internal class ExtraData
@@ -166,10 +166,10 @@ internal sealed class UnixTimeExtraField : ExtraData
return Tuple.Create(null, null, null);
}
- var flags = DataBytes[0];
- var isModifiedTimeSpecified = (flags & 0x01) == 1;
- var isLastAccessTimeSpecified = (flags & 0x02) == 1;
- var isCreationTimeSpecified = (flags & 0x04) == 1;
+ var flags = (RecordedTimeFlag)DataBytes[0];
+ var isModifiedTimeSpecified = flags.HasFlag(RecordedTimeFlag.LastModified);
+ var isLastAccessTimeSpecified = flags.HasFlag(RecordedTimeFlag.LastAccessed);
+ var isCreationTimeSpecified = flags.HasFlag(RecordedTimeFlag.Created);
var currentIndex = 1;
DateTime? modifiedTime = null;
DateTime? lastAccessTime = null;
@@ -189,7 +189,7 @@ internal sealed class UnixTimeExtraField : ExtraData
{
if (currentIndex + 4 > DataBytes.Length)
{
- throw new ArchiveException("Invalid UnicodeExtraTime field");
+ return Tuple.Create(null, null, null);
}
var lastAccessEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
@@ -206,7 +206,7 @@ internal sealed class UnixTimeExtraField : ExtraData
{
if (currentIndex + 4 > DataBytes.Length)
{
- throw new ArchiveException("Invalid UnicodeExtraTime field");
+ return Tuple.Create(null, null, null);
}
var creationTimeEpochTime = BinaryPrimitives.ReadInt32LittleEndian(
@@ -222,6 +222,15 @@ internal sealed class UnixTimeExtraField : ExtraData
return Tuple.Create(modifiedTime, lastAccessTime, creationTime);
}
}
+
+ [Flags]
+ private enum RecordedTimeFlag
+ {
+ None = 0,
+ LastModified = 1,
+ LastAccessed = 2,
+ Created = 4,
+ }
}
internal static class LocalEntryHeaderExtraFactory
@@ -229,11 +238,14 @@ internal static class LocalEntryHeaderExtraFactory
internal static ExtraData Create(ExtraDataType type, ushort length, byte[] extraData) =>
type switch
{
- ExtraDataType.UnicodePathExtraField
- => new ExtraUnicodePathExtraField(type, length, extraData),
- ExtraDataType.Zip64ExtendedInformationExtraField
- => new Zip64ExtendedInformationExtraField(type, length, extraData),
+ ExtraDataType.UnicodePathExtraField => new ExtraUnicodePathExtraField(
+ type,
+ length,
+ extraData
+ ),
+ ExtraDataType.Zip64ExtendedInformationExtraField =>
+ new Zip64ExtendedInformationExtraField(type, length, extraData),
ExtraDataType.UnixTimeExtraField => new UnixTimeExtraField(type, length, extraData),
- _ => new ExtraData(type, length, extraData)
+ _ => new ExtraData(type, length, extraData),
};
}
diff --git a/src/SharpCompress/Common/Zip/Headers/ZipHeaderType.cs b/src/SharpCompress/Common/Zip/Headers/ZipHeaderType.cs
index 62c29d89..75cce8d8 100644
--- a/src/SharpCompress/Common/Zip/Headers/ZipHeaderType.cs
+++ b/src/SharpCompress/Common/Zip/Headers/ZipHeaderType.cs
@@ -8,5 +8,5 @@ internal enum ZipHeaderType
DirectoryEnd,
Split,
Zip64DirectoryEnd,
- Zip64DirectoryEndLocator
+ Zip64DirectoryEndLocator,
}
diff --git a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
index 6ac48c6f..f8914c68 100644
--- a/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
+++ b/src/SharpCompress/Common/Zip/PkwareTraditionalCryptoStream.cs
@@ -6,7 +6,7 @@ namespace SharpCompress.Common.Zip;
internal enum CryptoMode
{
Encrypt,
- Decrypt
+ Decrypt,
}
internal class PkwareTraditionalCryptoStream : Stream
diff --git a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
index e37008e5..54c4f527 100644
--- a/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/SeekableZipFilePart.cs
@@ -1,6 +1,5 @@
using System.IO;
using SharpCompress.Common.Zip.Headers;
-using SharpCompress.IO;
namespace SharpCompress.Common.Zip;
@@ -8,18 +7,13 @@ internal class SeekableZipFilePart : ZipFilePart
{
private bool _isLocalHeaderLoaded;
private readonly SeekableZipHeaderFactory _headerFactory;
- private readonly DirectoryEntryHeader _directoryEntryHeader;
internal SeekableZipFilePart(
SeekableZipHeaderFactory headerFactory,
DirectoryEntryHeader header,
Stream stream
)
- : base(header, stream)
- {
- _headerFactory = headerFactory;
- _directoryEntryHeader = header;
- }
+ : base(header, stream) => _headerFactory = headerFactory;
internal override Stream GetCompressedStream()
{
@@ -44,16 +38,6 @@ internal class SeekableZipFilePart : ZipFilePart
{
BaseStream.Position = Header.DataStartPosition.NotNull();
- if (
- (Header.CompressedSize == 0)
- && FlagUtility.HasFlag(Header.Flags, HeaderFlags.UsePostDataDescriptor)
- && _directoryEntryHeader.HasData
- && (_directoryEntryHeader.CompressedSize != 0)
- )
- {
- return new ReadOnlySubStream(BaseStream, _directoryEntryHeader.CompressedSize);
- }
-
return BaseStream;
}
}
diff --git a/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs
index b99d0e2b..816b0b67 100644
--- a/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs
+++ b/src/SharpCompress/Common/Zip/SeekableZipHeaderFactory.cs
@@ -149,6 +149,12 @@ internal sealed class SeekableZipHeaderFactory : ZipHeaderFactory
{
throw new InvalidOperationException();
}
+ if (FlagUtility.HasFlag(localEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor))
+ {
+ localEntryHeader.Crc = directoryEntryHeader.Crc;
+ localEntryHeader.CompressedSize = directoryEntryHeader.CompressedSize;
+ localEntryHeader.UncompressedSize = directoryEntryHeader.UncompressedSize;
+ }
return localEntryHeader;
}
}
diff --git a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
index c0af5408..508dfd1a 100644
--- a/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
+++ b/src/SharpCompress/Common/Zip/StreamingZipHeaderFactory.cs
@@ -36,10 +36,7 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
uint headerBytes = 0;
if (
_lastEntryHeader != null
- && (
- FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
- || _lastEntryHeader.IsZip64
- )
+ && FlagUtility.HasFlag(_lastEntryHeader.Flags, HeaderFlags.UsePostDataDescriptor)
)
{
if (_lastEntryHeader.Part is null)
@@ -49,7 +46,9 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
ref rewindableStream
);
+
var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
+
var crc = reader.ReadUInt32();
if (crc == POST_DATA_DESCRIPTOR)
{
@@ -82,6 +81,60 @@ internal class StreamingZipHeaderFactory : ZipHeaderFactory
_lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
}
}
+ else if (_lastEntryHeader != null && _lastEntryHeader.IsZip64)
+ {
+ if (_lastEntryHeader.Part is null)
+ continue;
+
+ reader = ((StreamingZipFilePart)_lastEntryHeader.Part).FixStreamedFileLocation(
+ ref rewindableStream
+ );
+
+ var pos = rewindableStream.CanSeek ? (long?)rewindableStream.Position : null;
+
+ headerBytes = reader.ReadUInt32();
+
+ var version = reader.ReadUInt16();
+ var flags = (HeaderFlags)reader.ReadUInt16();
+ var compressionMethod = (ZipCompressionMethod)reader.ReadUInt16();
+ var lastModifiedDate = reader.ReadUInt16();
+ var lastModifiedTime = reader.ReadUInt16();
+
+ var crc = reader.ReadUInt32();
+
+ if (crc == POST_DATA_DESCRIPTOR)
+ {
+ crc = reader.ReadUInt32();
+ }
+ _lastEntryHeader.Crc = crc;
+
+ // The DataDescriptor can be either 64bit or 32bit
+ var compressed_size = reader.ReadUInt32();
+ var uncompressed_size = reader.ReadUInt32();
+
+ // Check if we have header or 64bit DataDescriptor
+ var test_header = !(headerBytes == 0x04034b50 || headerBytes == 0x02014b50);
+
+ var test_64bit = ((long)uncompressed_size << 32) | compressed_size;
+ if (test_64bit == _lastEntryHeader.CompressedSize && test_header)
+ {
+ _lastEntryHeader.UncompressedSize =
+ ((long)reader.ReadUInt32() << 32) | headerBytes;
+ headerBytes = reader.ReadUInt32();
+ }
+ else
+ {
+ _lastEntryHeader.UncompressedSize = uncompressed_size;
+ }
+
+ if (pos.HasValue)
+ {
+ _lastEntryHeader.DataStartPosition = pos - _lastEntryHeader.CompressedSize;
+
+ // 4 = First 4 bytes of the entry header (i.e. 50 4B 03 04)
+ rewindableStream.Position = pos.Value + 4;
+ }
+ }
else
{
headerBytes = reader.ReadUInt32();
diff --git a/src/SharpCompress/Common/Zip/WinzipAesKeySize.cs b/src/SharpCompress/Common/Zip/WinzipAesKeySize.cs
index 7772bcaa..276a3504 100644
--- a/src/SharpCompress/Common/Zip/WinzipAesKeySize.cs
+++ b/src/SharpCompress/Common/Zip/WinzipAesKeySize.cs
@@ -4,5 +4,5 @@ internal enum WinzipAesKeySize
{
KeySize128 = 1,
KeySize192 = 2,
- KeySize256 = 3
+ KeySize256 = 3,
}
diff --git a/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs b/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
index a98ed667..834197c0 100644
--- a/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
+++ b/src/SharpCompress/Common/Zip/ZipCompressionMethod.cs
@@ -4,6 +4,11 @@ internal enum ZipCompressionMethod
{
None = 0,
Shrink = 1,
+ Reduce1 = 2,
+ Reduce2 = 3,
+ Reduce3 = 4,
+ Reduce4 = 5,
+ Explode = 6,
Deflate = 8,
Deflate64 = 9,
BZip2 = 12,
@@ -11,5 +16,5 @@ internal enum ZipCompressionMethod
ZStd = 93,
Xz = 95,
PPMd = 98,
- WinzipAes = 0x63 //http://www.winzip.com/aes_info.htm
+ WinzipAes = 0x63, //http://www.winzip.com/aes_info.htm
}
diff --git a/src/SharpCompress/Common/Zip/ZipEntry.cs b/src/SharpCompress/Common/Zip/ZipEntry.cs
index c2cecf39..d8e947f8 100644
--- a/src/SharpCompress/Common/Zip/ZipEntry.cs
+++ b/src/SharpCompress/Common/Zip/ZipEntry.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Linq;
using SharpCompress.Common.Zip.Headers;
namespace SharpCompress.Common.Zip;
@@ -15,10 +16,19 @@ public class ZipEntry : Entry
return;
}
_filePart = filePart;
+
LastModifiedTime = Utility.DosDateToDateTime(
filePart.Header.LastModifiedDate,
filePart.Header.LastModifiedTime
);
+
+ var times =
+ filePart.Header.Extra.FirstOrDefault(header =>
+ header.GetType() == typeof(UnixTimeExtraField)
+ ) as UnixTimeExtraField;
+
+ LastAccessedTime = times?.UnicodeTimes.Item2;
+ CreatedTime = times?.UnicodeTimes.Item3;
}
public override CompressionType CompressionType =>
@@ -31,7 +41,12 @@ public class ZipEntry : Entry
ZipCompressionMethod.PPMd => CompressionType.PPMd,
ZipCompressionMethod.None => CompressionType.None,
ZipCompressionMethod.Shrink => CompressionType.Shrink,
- _ => CompressionType.Unknown
+ ZipCompressionMethod.Reduce1 => CompressionType.Reduce1,
+ ZipCompressionMethod.Reduce2 => CompressionType.Reduce2,
+ ZipCompressionMethod.Reduce3 => CompressionType.Reduce3,
+ ZipCompressionMethod.Reduce4 => CompressionType.Reduce4,
+ ZipCompressionMethod.Explode => CompressionType.Explode,
+ _ => CompressionType.Unknown,
};
public override long Crc => _filePart?.Header.Crc ?? 0;
@@ -46,9 +61,17 @@ public class ZipEntry : Entry
public override DateTime? LastModifiedTime { get; }
- public override DateTime? CreatedTime => null;
+ ///
+ ///
+ /// The returned time is UTC, not local.
+ ///
+ public override DateTime? CreatedTime { get; }
- public override DateTime? LastAccessedTime => null;
+ ///
+ ///
+ /// The returned time is UTC, not local.
+ ///
+ public override DateTime? LastAccessedTime { get; }
public override DateTime? ArchivedTime => null;
diff --git a/src/SharpCompress/Common/Zip/ZipFilePart.cs b/src/SharpCompress/Common/Zip/ZipFilePart.cs
index e8516150..85b566d9 100644
--- a/src/SharpCompress/Common/Zip/ZipFilePart.cs
+++ b/src/SharpCompress/Common/Zip/ZipFilePart.cs
@@ -7,8 +7,10 @@ using SharpCompress.Compressors;
using SharpCompress.Compressors.BZip2;
using SharpCompress.Compressors.Deflate;
using SharpCompress.Compressors.Deflate64;
+using SharpCompress.Compressors.Explode;
using SharpCompress.Compressors.LZMA;
using SharpCompress.Compressors.PPMd;
+using SharpCompress.Compressors.Reduce;
using SharpCompress.Compressors.Shrink;
using SharpCompress.Compressors.Xz;
using SharpCompress.IO;
@@ -89,6 +91,32 @@ internal abstract class ZipFilePart : FilePart
Header.UncompressedSize
);
}
+ case ZipCompressionMethod.Reduce1:
+ {
+ return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 1);
+ }
+ case ZipCompressionMethod.Reduce2:
+ {
+ return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 2);
+ }
+ case ZipCompressionMethod.Reduce3:
+ {
+ return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 3);
+ }
+ case ZipCompressionMethod.Reduce4:
+ {
+ return new ReduceStream(stream, Header.CompressedSize, Header.UncompressedSize, 4);
+ }
+ case ZipCompressionMethod.Explode:
+ {
+ return new ExplodeStream(
+ stream,
+ Header.CompressedSize,
+ Header.UncompressedSize,
+ Header.Flags
+ );
+ }
+
case ZipCompressionMethod.Deflate:
{
return new DeflateStream(stream, CompressionMode.Decompress);
@@ -203,6 +231,10 @@ internal abstract class ZipFilePart : FilePart
{
case ZipCompressionMethod.None:
case ZipCompressionMethod.Shrink:
+ case ZipCompressionMethod.Reduce1:
+ case ZipCompressionMethod.Reduce2:
+ case ZipCompressionMethod.Reduce3:
+ case ZipCompressionMethod.Reduce4:
case ZipCompressionMethod.Deflate:
case ZipCompressionMethod.Deflate64:
case ZipCompressionMethod.BZip2:
diff --git a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
index 40fe178f..45869ff6 100644
--- a/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
+++ b/src/SharpCompress/Common/Zip/ZipHeaderFactory.cs
@@ -56,11 +56,11 @@ internal class ZipHeaderFactory
case POST_DATA_DESCRIPTOR:
{
if (
- FlagUtility.HasFlag(
+ _lastEntryHeader != null
+ && FlagUtility.HasFlag(
_lastEntryHeader.NotNull().Flags,
HeaderFlags.UsePostDataDescriptor
)
- && _lastEntryHeader != null
)
{
_lastEntryHeader.Crc = reader.ReadUInt32();
diff --git a/src/SharpCompress/Compressors/BZip2/BZip2Constants.cs b/src/SharpCompress/Compressors/BZip2/BZip2Constants.cs
index cfeb02e4..85c63b39 100644
--- a/src/SharpCompress/Compressors/BZip2/BZip2Constants.cs
+++ b/src/SharpCompress/Compressors/BZip2/BZip2Constants.cs
@@ -555,6 +555,6 @@ internal class BZip2Constants
858,
364,
936,
- 638
+ 638,
};
}
diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
index a541a04d..a467942f 100644
--- a/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
+++ b/src/SharpCompress/Compressors/BZip2/CBZip2InputStream.cs
@@ -1,4 +1,4 @@
-#nullable disable
+#nullable disable
using System;
using System.IO;
@@ -42,14 +42,17 @@ internal class CBZip2InputStream : Stream
private static void Cadvise()
{
//System.out.Println("CRC Error");
- //throw new CCoruptionError();
+ throw new InvalidOperationException("BZip2 error");
}
private static void BadBGLengths() => Cadvise();
private static void BitStreamEOF() => Cadvise();
- private static void CompressedStreamEOF() => Cadvise();
+ private static void CompressedStreamEOF()
+ {
+ throw new InvalidOperationException("BZip2 compressed file ends unexpectedly");
+ }
private void MakeMaps()
{
diff --git a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
index bf01c2c3..5e78c5fa 100644
--- a/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
+++ b/src/SharpCompress/Compressors/BZip2/CBZip2OutputStream.cs
@@ -1829,7 +1829,7 @@ internal sealed class CBZip2OutputStream : Stream
88573,
265720,
797161,
- 2391484
+ 2391484,
};
private void AllocateCompressStructures()
diff --git a/src/SharpCompress/Compressors/BZip2/CRC.cs b/src/SharpCompress/Compressors/BZip2/CRC.cs
index 9f593c40..6e8e034a 100644
--- a/src/SharpCompress/Compressors/BZip2/CRC.cs
+++ b/src/SharpCompress/Compressors/BZip2/CRC.cs
@@ -288,7 +288,7 @@ internal class CRC
unchecked((int)0xbcb4666d),
unchecked((int)0xb8757bda),
unchecked((int)0xb5365d03),
- unchecked((int)0xb1f740b4)
+ unchecked((int)0xb1f740b4),
};
public CRC() => InitialiseCRC();
diff --git a/src/SharpCompress/Compressors/CompressionMode.cs b/src/SharpCompress/Compressors/CompressionMode.cs
index 4eba1121..0bf15e03 100644
--- a/src/SharpCompress/Compressors/CompressionMode.cs
+++ b/src/SharpCompress/Compressors/CompressionMode.cs
@@ -3,5 +3,5 @@ namespace SharpCompress.Compressors;
public enum CompressionMode
{
Compress = 0,
- Decompress = 1
+ Decompress = 1,
}
diff --git a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
index cccd0237..933f5752 100644
--- a/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
+++ b/src/SharpCompress/Compressors/Deflate/DeflateManager.cs
@@ -106,7 +106,7 @@ internal sealed partial class DeflateManager
5,
5,
5,
- 0
+ 0,
};
// extra bits for each distance code
@@ -141,7 +141,7 @@ internal sealed partial class DeflateManager
12,
12,
13,
- 13
+ 13,
};
internal enum BlockState
@@ -149,14 +149,14 @@ internal sealed partial class DeflateManager
NeedMore = 0, // block not completed, need more input or more output
BlockDone, // block flush performed
FinishStarted, // finish started, need only more output at next deflate
- FinishDone // finish done, accept no more input or output
+ FinishDone, // finish done, accept no more input or output
}
internal enum DeflateFlavor
{
Store,
Fast,
- Slow
+ Slow,
}
private const int MEM_LEVEL_MAX = 9;
@@ -214,7 +214,7 @@ internal sealed partial class DeflateManager
new Config(8, 16, 128, 128, DeflateFlavor.Slow),
new Config(8, 32, 128, 256, DeflateFlavor.Slow),
new Config(32, 128, 258, 1024, DeflateFlavor.Slow),
- new Config(32, 258, 258, 4096, DeflateFlavor.Slow)
+ new Config(32, 258, 258, 4096, DeflateFlavor.Slow),
};
private static readonly Config[] Table;
@@ -233,7 +233,7 @@ internal sealed partial class DeflateManager
"insufficient memory",
"buffer error",
"incompatible version",
- ""
+ "",
};
// preset dictionary flag in zlib header
@@ -1793,7 +1793,7 @@ internal sealed partial class DeflateManager
DeflateFlavor.Store => DeflateNone,
DeflateFlavor.Fast => DeflateFast,
DeflateFlavor.Slow => DeflateSlow,
- _ => DeflateFunction
+ _ => DeflateFunction,
};
internal int SetParams(CompressionLevel level, CompressionStrategy strategy)
diff --git a/src/SharpCompress/Compressors/Deflate/FlushType.cs b/src/SharpCompress/Compressors/Deflate/FlushType.cs
index bcf7fe10..446962a3 100644
--- a/src/SharpCompress/Compressors/Deflate/FlushType.cs
+++ b/src/SharpCompress/Compressors/Deflate/FlushType.cs
@@ -39,5 +39,5 @@ public enum FlushType
Full,
/// Signals the end of the compression/decompression stream.
- Finish
+ Finish,
}
diff --git a/src/SharpCompress/Compressors/Deflate/InfTree.cs b/src/SharpCompress/Compressors/Deflate/InfTree.cs
index 74f4069d..2ea4cbc4 100644
--- a/src/SharpCompress/Compressors/Deflate/InfTree.cs
+++ b/src/SharpCompress/Compressors/Deflate/InfTree.cs
@@ -1615,7 +1615,7 @@ internal sealed class InfTree
79,
0,
9,
- 255
+ 255,
};
//UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
@@ -1716,7 +1716,7 @@ internal sealed class InfTree
193,
192,
5,
- 24577
+ 24577,
};
// Tables for deflate from PKZIP's appnote.txt.
@@ -1753,7 +1753,7 @@ internal sealed class InfTree
227,
258,
0,
- 0
+ 0,
};
// see note #13 above about 258
@@ -1790,7 +1790,7 @@ internal sealed class InfTree
5,
0,
112,
- 112
+ 112,
};
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
@@ -1825,7 +1825,7 @@ internal sealed class InfTree
8193,
12289,
16385,
- 24577
+ 24577,
};
//UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'"
@@ -1860,7 +1860,7 @@ internal sealed class InfTree
12,
12,
13,
- 13
+ 13,
};
// If BMAX needs to be larger than 16, then h and x[] should be uLong.
diff --git a/src/SharpCompress/Compressors/Deflate/Inflate.cs b/src/SharpCompress/Compressors/Deflate/Inflate.cs
index d768548b..fd1c764a 100644
--- a/src/SharpCompress/Compressors/Deflate/Inflate.cs
+++ b/src/SharpCompress/Compressors/Deflate/Inflate.cs
@@ -93,7 +93,7 @@ internal sealed class InflateBlocks
2,
14,
1,
- 15
+ 15,
};
internal ZlibCodec _codec; // pointer back to this zlib stream
@@ -815,7 +815,7 @@ internal sealed class InflateBlocks
CODES = 6, // processing fixed or dynamic block
DRY = 7, // output remaining window bytes
DONE = 8, // finished last block, done
- BAD = 9 // ot a data error--stuck here
+ BAD = 9, // ot a data error--stuck here
}
#endregion
@@ -842,7 +842,7 @@ internal static class InternalInflateConstants
0x00001fff,
0x00003fff,
0x00007fff,
- 0x0000ffff
+ 0x0000ffff,
};
}
@@ -2054,7 +2054,7 @@ internal sealed class InflateManager
CHECK2 = 10, // two check bytes to go
CHECK1 = 11, // one check byte to go
DONE = 12, // finished check, done
- BAD = 13 // got an error--stay here
+ BAD = 13, // got an error--stay here
}
#endregion
diff --git a/src/SharpCompress/Compressors/Deflate/Tree.cs b/src/SharpCompress/Compressors/Deflate/Tree.cs
index ec1eb51f..e5c9b52a 100644
--- a/src/SharpCompress/Compressors/Deflate/Tree.cs
+++ b/src/SharpCompress/Compressors/Deflate/Tree.cs
@@ -95,7 +95,7 @@ internal sealed partial class DeflateManager
2,
14,
1,
- 15
+ 15,
};
// The lengths of the bit length codes are sent in order of decreasing
@@ -618,7 +618,7 @@ internal sealed partial class DeflateManager
29,
29,
29,
- 29
+ 29,
};
internal static readonly sbyte[] LengthCode =
@@ -878,7 +878,7 @@ internal sealed partial class DeflateManager
27,
27,
27,
- 28
+ 28,
};
internal static readonly int[] LengthBase =
@@ -911,7 +911,7 @@ internal sealed partial class DeflateManager
160,
192,
224,
- 0
+ 0,
};
internal static readonly int[] DistanceBase =
@@ -945,7 +945,7 @@ internal sealed partial class DeflateManager
8192,
12288,
16384,
- 24576
+ 24576,
};
internal short[] dyn_tree; // the dynamic tree
diff --git a/src/SharpCompress/Compressors/Deflate/Zlib.cs b/src/SharpCompress/Compressors/Deflate/Zlib.cs
index 1358e01b..9ba751d8 100644
--- a/src/SharpCompress/Compressors/Deflate/Zlib.cs
+++ b/src/SharpCompress/Compressors/Deflate/Zlib.cs
@@ -143,7 +143,7 @@ public enum CompressionLevel
///
/// A synonym for BestCompression.
///
- Level9 = BestCompression
+ Level9 = BestCompression,
}
///
@@ -171,7 +171,7 @@ public enum CompressionStrategy
/// Using HuffmanOnly will force the compressor to do Huffman encoding only, with no
/// string matching.
///
- HuffmanOnly = 2
+ HuffmanOnly = 2,
}
///
@@ -859,7 +859,7 @@ internal sealed class StaticTree
99,
8,
227,
- 8
+ 8,
};
internal static readonly short[] distTreeCodes =
@@ -923,7 +923,7 @@ internal sealed class StaticTree
7,
5,
23,
- 5
+ 5,
};
// extra bits for each bit length code
@@ -947,7 +947,7 @@ internal sealed class StaticTree
0,
2,
3,
- 7
+ 7,
};
internal static readonly StaticTree Literals;
diff --git a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
index 94b1491d..f6372dff 100644
--- a/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
+++ b/src/SharpCompress/Compressors/Deflate/ZlibBaseStream.cs
@@ -39,7 +39,7 @@ internal enum ZlibStreamFlavor
{
ZLIB = 1950,
DEFLATE = 1951,
- GZIP = 1952
+ GZIP = 1952,
}
internal class ZlibBaseStream : Stream
@@ -655,6 +655,6 @@ internal class ZlibBaseStream : Stream
{
Writer,
Reader,
- Undefined
+ Undefined,
}
}
diff --git a/src/SharpCompress/Compressors/Deflate64/BlockType.cs b/src/SharpCompress/Compressors/Deflate64/BlockType.cs
index 5bd9eb83..b34ca903 100644
--- a/src/SharpCompress/Compressors/Deflate64/BlockType.cs
+++ b/src/SharpCompress/Compressors/Deflate64/BlockType.cs
@@ -8,5 +8,5 @@ internal enum BlockType
{
Uncompressed = 0,
Static = 1,
- Dynamic = 2
+ Dynamic = 2,
}
diff --git a/src/SharpCompress/Compressors/Deflate64/FastEncoderStatus.cs b/src/SharpCompress/Compressors/Deflate64/FastEncoderStatus.cs
index 71e3f680..37dafc68 100644
--- a/src/SharpCompress/Compressors/Deflate64/FastEncoderStatus.cs
+++ b/src/SharpCompress/Compressors/Deflate64/FastEncoderStatus.cs
@@ -111,7 +111,7 @@ internal static class FastEncoderStatics
0x7e,
0x7c,
0x1f,
- 0x3f
+ 0x3f,
};
internal static ReadOnlySpan B_FINAL_FAST_ENCODER_TREE_STRUCTURE_DATA =>
@@ -214,7 +214,7 @@ internal static class FastEncoderStatics
0x7e,
0x7c,
0x1f,
- 0x3f
+ 0x3f,
};
// Output a currentMatch with length matchLen (>= MIN_MATCH) and displacement matchPos
@@ -762,7 +762,7 @@ internal static class FastEncoderStatics
0x0039e7f1,
0x003be7f1,
0x003de7f1,
- 0x000047eb
+ 0x000047eb,
};
internal static readonly uint[] FAST_ENCODER_DISTANCE_CODE_INFO =
@@ -798,7 +798,7 @@ internal static class FastEncoderStatics
0x000007d5,
0x000017d5,
0x00000000,
- 0x00000100
+ 0x00000100,
};
internal static readonly uint[] BIT_MASK =
@@ -818,7 +818,7 @@ internal static class FastEncoderStatics
4095,
8191,
16383,
- 32767
+ 32767,
};
internal static readonly byte[] EXTRA_LENGTH_BITS =
{
@@ -850,7 +850,7 @@ internal static class FastEncoderStatics
5,
5,
5,
- 0
+ 0,
};
internal static readonly byte[] EXTRA_DISTANCE_BITS =
{
@@ -885,7 +885,7 @@ internal static class FastEncoderStatics
13,
13,
0,
- 0
+ 0,
};
internal const int NUM_CHARS = 256;
internal const int NUM_LENGTH_BASE_CODES = 29;
diff --git a/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs b/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
index 101188db..5caf257d 100644
--- a/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
+++ b/src/SharpCompress/Compressors/Deflate64/InflaterManaged.cs
@@ -70,7 +70,7 @@ internal sealed class InflaterManaged
5,
5,
5,
- 16
+ 16,
};
// The base length for length code 257 - 285.
@@ -105,7 +105,7 @@ internal sealed class InflaterManaged
163,
195,
227,
- 3
+ 3,
};
// The base distance for distance code 0 - 31
@@ -143,7 +143,7 @@ internal sealed class InflaterManaged
16385,
24577,
32769,
- 49153
+ 49153,
};
// code lengths for code length alphabet is stored in following order
@@ -184,7 +184,7 @@ internal sealed class InflaterManaged
0x07,
0x17,
0x0f,
- 0x1f
+ 0x1f,
};
private readonly OutputWindow _output;
diff --git a/src/SharpCompress/Compressors/Deflate64/InflaterState.cs b/src/SharpCompress/Compressors/Deflate64/InflaterState.cs
index 711c3245..16d627e0 100644
--- a/src/SharpCompress/Compressors/Deflate64/InflaterState.cs
+++ b/src/SharpCompress/Compressors/Deflate64/InflaterState.cs
@@ -37,5 +37,5 @@ internal enum InflaterState
ReadingFooter = 22,
VerifyingFooter = 23,
- Done = 24 // Finished
+ Done = 24, // Finished
}
diff --git a/src/SharpCompress/Compressors/Deflate64/MatchState.cs b/src/SharpCompress/Compressors/Deflate64/MatchState.cs
index 858e91e8..cabc0bad 100644
--- a/src/SharpCompress/Compressors/Deflate64/MatchState.cs
+++ b/src/SharpCompress/Compressors/Deflate64/MatchState.cs
@@ -8,5 +8,5 @@ internal enum MatchState
{
HasSymbol = 1,
HasMatch = 2,
- HasSymbolAndMatch = 3
+ HasSymbolAndMatch = 3,
}
diff --git a/src/SharpCompress/Compressors/Explode/ExplodeStream.cs b/src/SharpCompress/Compressors/Explode/ExplodeStream.cs
new file mode 100644
index 00000000..11a016e0
--- /dev/null
+++ b/src/SharpCompress/Compressors/Explode/ExplodeStream.cs
@@ -0,0 +1,746 @@
+using System;
+using System.IO;
+using SharpCompress.Common.Zip.Headers;
+
+namespace SharpCompress.Compressors.Explode;
+
+public class ExplodeStream : Stream
+{
+ private const int INVALID_CODE = 99;
+ private const int WSIZE = 64 * 1024;
+
+ private readonly long unCompressedSize;
+ private readonly int compressedSize;
+ private readonly HeaderFlags generalPurposeBitFlag;
+ private readonly Stream inStream;
+
+ private huftNode[]? hufLiteralCodeTable; /* literal code table */
+ private huftNode[] hufLengthCodeTable = []; /* length code table */
+ private huftNode[] hufDistanceCodeTable = []; /* distance code table */
+
+ private int bitsForLiteralCodeTable;
+ private int bitsForLengthCodeTable;
+ private int bitsForDistanceCodeTable;
+ private int numOfUncodedLowerDistanceBits; /* number of uncoded lower distance bits */
+
+ private ulong bitBuffer;
+ private int bitBufferCount;
+
+ private readonly byte[] windowsBuffer;
+ private uint maskForLiteralCodeTable;
+ private uint maskForLengthCodeTable;
+ private uint maskForDistanceCodeTable;
+ private uint maskForDistanceLowBits;
+ private long outBytesCount;
+
+ private int windowIndex;
+ private int distance;
+ private int length;
+
+ internal ExplodeStream(
+ Stream inStr,
+ long compressedSize,
+ long uncompressedSize,
+ HeaderFlags generalPurposeBitFlag
+ )
+ {
+ inStream = inStr;
+ this.compressedSize = (int)compressedSize;
+ unCompressedSize = (long)uncompressedSize;
+ this.generalPurposeBitFlag = generalPurposeBitFlag;
+ explode_SetTables();
+
+ windowsBuffer = new byte[WSIZE];
+ explode_var_init();
+ }
+
+ public override void Flush()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override bool CanRead => true;
+ public override bool CanSeek => false;
+ public override bool CanWrite => false;
+ public override long Length => unCompressedSize;
+ public override long Position
+ {
+ get => outBytesCount;
+ set { }
+ }
+
+ static uint[] mask_bits = new uint[]
+ {
+ 0x0000,
+ 0x0001,
+ 0x0003,
+ 0x0007,
+ 0x000f,
+ 0x001f,
+ 0x003f,
+ 0x007f,
+ 0x00ff,
+ 0x01ff,
+ 0x03ff,
+ 0x07ff,
+ 0x0fff,
+ 0x1fff,
+ 0x3fff,
+ 0x7fff,
+ 0xffff,
+ };
+
+ /* Tables for length and distance */
+ static int[] cplen2 = new int[]
+ {
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ };
+
+ static int[] cplen3 = new int[]
+ {
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36,
+ 37,
+ 38,
+ 39,
+ 40,
+ 41,
+ 42,
+ 43,
+ 44,
+ 45,
+ 46,
+ 47,
+ 48,
+ 49,
+ 50,
+ 51,
+ 52,
+ 53,
+ 54,
+ 55,
+ 56,
+ 57,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 66,
+ };
+
+ static int[] extra = new int[]
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 8,
+ };
+
+ static int[] cpdist4 = new int[]
+ {
+ 1,
+ 65,
+ 129,
+ 193,
+ 257,
+ 321,
+ 385,
+ 449,
+ 513,
+ 577,
+ 641,
+ 705,
+ 769,
+ 833,
+ 897,
+ 961,
+ 1025,
+ 1089,
+ 1153,
+ 1217,
+ 1281,
+ 1345,
+ 1409,
+ 1473,
+ 1537,
+ 1601,
+ 1665,
+ 1729,
+ 1793,
+ 1857,
+ 1921,
+ 1985,
+ 2049,
+ 2113,
+ 2177,
+ 2241,
+ 2305,
+ 2369,
+ 2433,
+ 2497,
+ 2561,
+ 2625,
+ 2689,
+ 2753,
+ 2817,
+ 2881,
+ 2945,
+ 3009,
+ 3073,
+ 3137,
+ 3201,
+ 3265,
+ 3329,
+ 3393,
+ 3457,
+ 3521,
+ 3585,
+ 3649,
+ 3713,
+ 3777,
+ 3841,
+ 3905,
+ 3969,
+ 4033,
+ };
+
+ static int[] cpdist8 = new int[]
+ {
+ 1,
+ 129,
+ 257,
+ 385,
+ 513,
+ 641,
+ 769,
+ 897,
+ 1025,
+ 1153,
+ 1281,
+ 1409,
+ 1537,
+ 1665,
+ 1793,
+ 1921,
+ 2049,
+ 2177,
+ 2305,
+ 2433,
+ 2561,
+ 2689,
+ 2817,
+ 2945,
+ 3073,
+ 3201,
+ 3329,
+ 3457,
+ 3585,
+ 3713,
+ 3841,
+ 3969,
+ 4097,
+ 4225,
+ 4353,
+ 4481,
+ 4609,
+ 4737,
+ 4865,
+ 4993,
+ 5121,
+ 5249,
+ 5377,
+ 5505,
+ 5633,
+ 5761,
+ 5889,
+ 6017,
+ 6145,
+ 6273,
+ 6401,
+ 6529,
+ 6657,
+ 6785,
+ 6913,
+ 7041,
+ 7169,
+ 7297,
+ 7425,
+ 7553,
+ 7681,
+ 7809,
+ 7937,
+ 8065,
+ };
+
+ private int get_tree(int[] arrBitLengths, int numberExpected)
+ /* Get the bit lengths for a code representation from the compressed
+ stream. If get_tree() returns 4, then there is an error in the data.
+ Otherwise zero is returned. */
+ {
+ /* get bit lengths */
+ int inIndex = inStream.ReadByte() + 1; /* length/count pairs to read */
+ int outIndex = 0; /* next code */
+ do
+ {
+ int nextByte = inStream.ReadByte();
+ int bitLengthOfCodes = (nextByte & 0xf) + 1; /* bits in code (1..16) */
+ int numOfCodes = ((nextByte & 0xf0) >> 4) + 1; /* codes with those bits (1..16) */
+ if (outIndex + numOfCodes > numberExpected)
+ return 4; /* don't overflow arrBitLengths[] */
+ do
+ {
+ arrBitLengths[outIndex++] = bitLengthOfCodes;
+ } while ((--numOfCodes) != 0);
+ } while ((--inIndex) != 0);
+
+ return outIndex != numberExpected ? 4 : 0; /* should have read numberExpected of them */
+ }
+
+ private int explode_SetTables()
+ {
+ int returnCode; /* return codes */
+ int[] arrBitLengthsForCodes = new int[256]; /* bit lengths for codes */
+
+ bitsForLiteralCodeTable = 0; /* bits for tb */
+ bitsForLengthCodeTable = 7;
+ bitsForDistanceCodeTable = (compressedSize) > 200000 ? 8 : 7;
+
+ if ((generalPurposeBitFlag & HeaderFlags.Bit2) != 0)
+ /* With literal tree--minimum match length is 3 */
+ {
+ bitsForLiteralCodeTable = 9; /* base table size for literals */
+ if ((returnCode = get_tree(arrBitLengthsForCodes, 256)) != 0)
+ return returnCode;
+
+ if (
+ (
+ returnCode = HuftTree.huftbuid(
+ arrBitLengthsForCodes,
+ 256,
+ 256,
+ [],
+ [],
+ out hufLiteralCodeTable,
+ ref bitsForLiteralCodeTable
+ )
+ ) != 0
+ )
+ return returnCode;
+
+ if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
+ return returnCode;
+
+ if (
+ (
+ returnCode = HuftTree.huftbuid(
+ arrBitLengthsForCodes,
+ 64,
+ 0,
+ cplen3,
+ extra,
+ out hufLengthCodeTable,
+ ref bitsForLengthCodeTable
+ )
+ ) != 0
+ )
+ return returnCode;
+ }
+ else
+ /* No literal tree--minimum match length is 2 */
+ {
+ if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
+ return returnCode;
+
+ hufLiteralCodeTable = null;
+
+ if (
+ (
+ returnCode = HuftTree.huftbuid(
+ arrBitLengthsForCodes,
+ 64,
+ 0,
+ cplen2,
+ extra,
+ out hufLengthCodeTable,
+ ref bitsForLengthCodeTable
+ )
+ ) != 0
+ )
+ return returnCode;
+ }
+
+ if ((returnCode = get_tree(arrBitLengthsForCodes, 64)) != 0)
+ return (int)returnCode;
+
+ if ((generalPurposeBitFlag & HeaderFlags.Bit1) != 0) /* true if 8K */
+ {
+ numOfUncodedLowerDistanceBits = 7;
+ returnCode = HuftTree.huftbuid(
+ arrBitLengthsForCodes,
+ 64,
+ 0,
+ cpdist8,
+ extra,
+ out hufDistanceCodeTable,
+ ref bitsForDistanceCodeTable
+ );
+ }
+ else /* else 4K */
+ {
+ numOfUncodedLowerDistanceBits = 6;
+ returnCode = HuftTree.huftbuid(
+ arrBitLengthsForCodes,
+ 64,
+ 0,
+ cpdist4,
+ extra,
+ out hufDistanceCodeTable,
+ ref bitsForDistanceCodeTable
+ );
+ }
+
+ return returnCode;
+ }
+
+ private void NeedBits(int numberOfBits)
+ {
+ while (bitBufferCount < (numberOfBits))
+ {
+ bitBuffer |= (uint)inStream.ReadByte() << bitBufferCount;
+ bitBufferCount += 8;
+ }
+ }
+
+ private void DumpBits(int numberOfBits)
+ {
+ bitBuffer >>= numberOfBits;
+ bitBufferCount -= numberOfBits;
+ }
+
+ int DecodeHuft(huftNode[] htab, int bits, uint mask, out huftNode huftPointer, out int e)
+ {
+ NeedBits(bits);
+
+ int tabOffset = (int)(~bitBuffer & mask);
+ huftPointer = htab[tabOffset];
+
+ while (true)
+ {
+ DumpBits(huftPointer.NumberOfBitsUsed);
+ e = huftPointer.NumberOfExtraBits;
+ if (e <= 32)
+ break;
+ if (e == INVALID_CODE)
+ return 1;
+
+ e &= 31;
+ NeedBits(e);
+
+ tabOffset = (int)(~bitBuffer & mask_bits[e]);
+ huftPointer = huftPointer.ChildNodes[tabOffset];
+ }
+
+ return 0;
+ }
+
+ private void explode_var_init()
+ {
+ /* explode the coded data */
+ bitBuffer = 0;
+ bitBufferCount = 0;
+ maskForLiteralCodeTable = mask_bits[bitsForLiteralCodeTable]; //only used in explode_lit
+ maskForLengthCodeTable = mask_bits[bitsForLengthCodeTable];
+ maskForDistanceCodeTable = mask_bits[bitsForDistanceCodeTable];
+ maskForDistanceLowBits = mask_bits[numOfUncodedLowerDistanceBits];
+ outBytesCount = 0;
+
+ windowIndex = 0; /* initialize bit buffer, window */
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ int countIndex = 0;
+ while (countIndex < count && outBytesCount < unCompressedSize) /* do until unCompressedSize bytes uncompressed */
+ {
+ if (length == 0)
+ {
+ NeedBits(1);
+ bool literal = (bitBuffer & 1) == 1;
+ DumpBits(1);
+
+ huftNode huftPointer;
+ if (literal) /* then literal--decode it */
+ {
+ byte nextByte;
+ if (hufLiteralCodeTable != null)
+ {
+ /* get coded literal */
+ if (
+ DecodeHuft(
+ hufLiteralCodeTable,
+ bitsForLiteralCodeTable,
+ maskForLiteralCodeTable,
+ out huftPointer,
+ out _
+ ) != 0
+ )
+ throw new Exception("Error decoding literal value");
+
+ nextByte = (byte)huftPointer.Value;
+ }
+ else
+ {
+ NeedBits(8);
+ nextByte = (byte)bitBuffer;
+ DumpBits(8);
+ }
+
+ buffer[offset + (countIndex++)] = nextByte;
+ windowsBuffer[windowIndex++] = nextByte;
+ outBytesCount++;
+
+ if (windowIndex == WSIZE)
+ windowIndex = 0;
+
+ continue;
+ }
+
+ NeedBits(numOfUncodedLowerDistanceBits); /* get distance low bits */
+ distance = (int)(bitBuffer & maskForDistanceLowBits);
+ DumpBits(numOfUncodedLowerDistanceBits);
+
+ /* get coded distance high bits */
+ if (
+ DecodeHuft(
+ hufDistanceCodeTable,
+ bitsForDistanceCodeTable,
+ maskForDistanceCodeTable,
+ out huftPointer,
+ out _
+ ) != 0
+ )
+ throw new Exception("Error decoding distance high bits");
+
+ distance = windowIndex - (distance + huftPointer.Value); /* construct offset */
+
+ /* get coded length */
+ if (
+ DecodeHuft(
+ hufLengthCodeTable,
+ bitsForLengthCodeTable,
+ maskForLengthCodeTable,
+ out huftPointer,
+ out int extraBitLength
+ ) != 0
+ )
+ throw new Exception("Error decoding coded length");
+
+ length = huftPointer.Value;
+
+ if (extraBitLength != 0) /* get length extra bits */
+ {
+ NeedBits(8);
+ length += (int)(bitBuffer & 0xff);
+ DumpBits(8);
+ }
+
+ if (length > (unCompressedSize - outBytesCount))
+ length = (int)(unCompressedSize - outBytesCount);
+
+ distance &= WSIZE - 1;
+ }
+
+ while (length != 0 && countIndex < count)
+ {
+ byte nextByte = windowsBuffer[distance++];
+ buffer[offset + (countIndex++)] = nextByte;
+ windowsBuffer[windowIndex++] = nextByte;
+ outBytesCount++;
+
+ if (distance == WSIZE)
+ distance = 0;
+
+ if (windowIndex == WSIZE)
+ windowIndex = 0;
+
+ length--;
+ }
+ }
+
+ return countIndex;
+ }
+}
diff --git a/src/SharpCompress/Compressors/Explode/HuftTree.cs b/src/SharpCompress/Compressors/Explode/HuftTree.cs
new file mode 100644
index 00000000..d216cfc7
--- /dev/null
+++ b/src/SharpCompress/Compressors/Explode/HuftTree.cs
@@ -0,0 +1,269 @@
+/*
+ * This code has been converted to C# based on the original huft_tree code found in
+ * inflate.c -- by Mark Adler version c17e, 30 Mar 2007
+ */
+
+namespace SharpCompress.Compressors.Explode;
+
+public class huftNode
+{
+ public int NumberOfExtraBits; /* number of extra bits or operation */
+ public int NumberOfBitsUsed; /* number of bits in this code or subcode */
+ public int Value; /* literal, length base, or distance base */
+ public huftNode[] ChildNodes = []; /* next level of table */
+}
+
+public static class HuftTree
+{
+ private const int INVALID_CODE = 99;
+
+ /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+ private const int BMAX = 16; /* maximum bit length of any code (16 for explode) */
+ private const int N_MAX = 288; /* maximum number of codes in any set */
+
+ public static int huftbuid(
+ int[] arrBitLengthForCodes,
+ int numberOfCodes,
+ int numberOfSimpleValueCodes,
+ int[] arrBaseValuesForNonSimpleCodes,
+ int[] arrExtraBitsForNonSimpleCodes,
+ out huftNode[] outHufTable,
+ ref int outBitsForTable
+ )
+ /* Given a list of code lengths and a maximum table size, make a set of
+ tables to decode that set of codes. Return zero on success, one if
+ the given code set is incomplete (the tables are still built in this
+ case), two if the input is invalid (all zero length codes or an
+ oversubscribed set of lengths), and three if not enough memory.
+ The code with value 256 is special, and the tables are constructed
+ so that no bits beyond that code are fetched when that code is
+ decoded. */
+ {
+ outHufTable = [];
+
+ /* Generate counts for each bit length */
+ int lengthOfEOBcode = numberOfCodes > 256 ? arrBitLengthForCodes[256] : BMAX; /* set length of EOB code, if any */
+
+ int[] arrBitLengthCount = new int[BMAX + 1];
+ for (int i = 0; i < BMAX + 1; i++)
+ arrBitLengthCount[i] = 0;
+
+ int pIndex = 0;
+ int counterCurrentCode = numberOfCodes;
+ do
+ {
+ arrBitLengthCount[arrBitLengthForCodes[pIndex]]++;
+ pIndex++; /* assume all entries <= BMAX */
+ } while ((--counterCurrentCode) != 0);
+
+ if (arrBitLengthCount[0] == numberOfCodes) /* null input--all zero length codes */
+ {
+ return 0;
+ }
+
+ /* Find minimum and maximum length, bound *outBitsForTable by those */
+ int counter;
+ for (counter = 1; counter <= BMAX; counter++)
+ if (arrBitLengthCount[counter] != 0)
+ break;
+
+ int numberOfBitsInCurrentCode = counter; /* minimum code length */
+ if (outBitsForTable < counter)
+ outBitsForTable = counter;
+
+ for (counterCurrentCode = BMAX; counterCurrentCode != 0; counterCurrentCode--)
+ if (arrBitLengthCount[counterCurrentCode] != 0)
+ break;
+
+ int maximumCodeLength = counterCurrentCode; /* maximum code length */
+ if (outBitsForTable > counterCurrentCode)
+ outBitsForTable = counterCurrentCode;
+
+ /* Adjust last length count to fill out codes, if needed */
+ int numberOfDummyCodesAdded;
+ for (
+ numberOfDummyCodesAdded = 1 << counter;
+ counter < counterCurrentCode;
+ counter++, numberOfDummyCodesAdded <<= 1
+ )
+ if ((numberOfDummyCodesAdded -= arrBitLengthCount[counter]) < 0)
+ return 2; /* bad input: more codes than bits */
+
+ if ((numberOfDummyCodesAdded -= arrBitLengthCount[counterCurrentCode]) < 0)
+ return 2;
+
+ arrBitLengthCount[counterCurrentCode] += numberOfDummyCodesAdded;
+
+ /* Generate starting offsets into the value table for each length */
+ int[] bitOffset = new int[BMAX + 1];
+ bitOffset[1] = 0;
+ counter = 0;
+ pIndex = 1;
+ int xIndex = 2;
+ while ((--counterCurrentCode) != 0)
+ { /* note that i == g from above */
+ bitOffset[xIndex++] = (counter += arrBitLengthCount[pIndex++]);
+ }
+
+ /* Make a table of values in order of bit lengths */
+ int[] arrValuesInOrderOfBitLength = new int[N_MAX];
+ for (int i = 0; i < N_MAX; i++)
+ arrValuesInOrderOfBitLength[i] = 0;
+
+ pIndex = 0;
+ counterCurrentCode = 0;
+ do
+ {
+ if ((counter = arrBitLengthForCodes[pIndex++]) != 0)
+ arrValuesInOrderOfBitLength[bitOffset[counter]++] = counterCurrentCode;
+ } while (++counterCurrentCode < numberOfCodes);
+
+ numberOfCodes = bitOffset[maximumCodeLength]; /* set numberOfCodes to length of v */
+
+ /* Generate the Huffman codes and for each, make the table entries */
+ bitOffset[0] = counterCurrentCode = 0; /* first Huffman code is zero */
+ pIndex = 0; /* grab values in bit order */
+ int tableLevel = -1; /* no tables yet--level -1 */
+ int bitsBeforeThisTable = 0;
+ int[] arrLX = new int[BMAX + 1];
+ int stackOfBitsPerTable = 1; /* stack of bits per table */
+ arrLX[stackOfBitsPerTable - 1] = 0; /* no bits decoded yet */
+
+ huftNode[][] arrHufTableStack = new huftNode[BMAX][];
+ huftNode[] pointerToCurrentTable = [];
+ int numberOfEntriesInCurrentTable = 0;
+
+ bool first = true;
+
+ /* go through the bit lengths (k already is bits in shortest code) */
+ for (; numberOfBitsInCurrentCode <= maximumCodeLength; numberOfBitsInCurrentCode++)
+ {
+ int counterForCodes = arrBitLengthCount[numberOfBitsInCurrentCode];
+ while ((counterForCodes--) != 0)
+ {
+ /* here i is the Huffman code of length k bits for value *p */
+ /* make tables up to required level */
+ while (
+ numberOfBitsInCurrentCode
+ > bitsBeforeThisTable + arrLX[stackOfBitsPerTable + tableLevel]
+ )
+ {
+ bitsBeforeThisTable += arrLX[stackOfBitsPerTable + (tableLevel++)]; /* add bits already decoded */
+
+ /* compute minimum size table less than or equal to *outBitsForTable bits */
+ numberOfEntriesInCurrentTable =
+ (numberOfEntriesInCurrentTable = maximumCodeLength - bitsBeforeThisTable)
+ > outBitsForTable
+ ? outBitsForTable
+ : numberOfEntriesInCurrentTable; /* upper limit */
+ int fBitCounter1 =
+ 1 << (counter = numberOfBitsInCurrentCode - bitsBeforeThisTable);
+ if (fBitCounter1 > counterForCodes + 1) /* try a k-w bit table */
+ { /* too few codes for k-w bit table */
+ fBitCounter1 -= counterForCodes + 1; /* deduct codes from patterns left */
+ xIndex = numberOfBitsInCurrentCode;
+ while (++counter < numberOfEntriesInCurrentTable) /* try smaller tables up to z bits */
+ {
+ if ((fBitCounter1 <<= 1) <= arrBitLengthCount[++xIndex])
+ break; /* enough codes to use up j bits */
+ fBitCounter1 -= arrBitLengthCount[xIndex]; /* else deduct codes from patterns */
+ }
+ }
+ if (
+ bitsBeforeThisTable + counter > lengthOfEOBcode
+ && bitsBeforeThisTable < lengthOfEOBcode
+ )
+ counter = lengthOfEOBcode - bitsBeforeThisTable; /* make EOB code end at table */
+
+ numberOfEntriesInCurrentTable = 1 << counter; /* table entries for j-bit table */
+ arrLX[stackOfBitsPerTable + tableLevel] = counter; /* set table size in stack */
+
+ /* allocate and link in new table */
+ pointerToCurrentTable = new huftNode[numberOfEntriesInCurrentTable];
+
+ // set the pointer, pointed to by *outHufTable to the second huft in pointertoCurrentTable
+ if (first)
+ {
+ outHufTable = pointerToCurrentTable; /* link to list for huft_free() */
+ first = false;
+ }
+
+ arrHufTableStack[tableLevel] = pointerToCurrentTable; /* table starts after link */
+
+ /* connect to last table, if there is one */
+ if (tableLevel != 0)
+ {
+ bitOffset[tableLevel] = counterCurrentCode; /* save pattern for backing up */
+
+ huftNode vHuft = new huftNode
+ {
+ NumberOfBitsUsed = arrLX[stackOfBitsPerTable + tableLevel - 1], /* bits to dump before this table */
+ NumberOfExtraBits = 32 + counter, /* bits in this table */
+ ChildNodes = pointerToCurrentTable, /* pointer to this table */
+ };
+
+ counter =
+ (counterCurrentCode & ((1 << bitsBeforeThisTable) - 1))
+ >> (bitsBeforeThisTable - arrLX[stackOfBitsPerTable + tableLevel - 1]);
+ arrHufTableStack[tableLevel - 1][counter] = vHuft; /* connect to last table */
+ }
+ }
+
+ /* set up table entry in r */
+ huftNode vHuft1 = new huftNode
+ {
+ NumberOfBitsUsed = numberOfBitsInCurrentCode - bitsBeforeThisTable,
+ };
+
+ if (pIndex >= numberOfCodes)
+ vHuft1.NumberOfExtraBits = INVALID_CODE; /* out of values--invalid code */
+ else if (arrValuesInOrderOfBitLength[pIndex] < numberOfSimpleValueCodes)
+ {
+ vHuft1.NumberOfExtraBits = (
+ arrValuesInOrderOfBitLength[pIndex] < 256 ? 32 : 31
+ ); /* 256 is end-of-block code */
+ vHuft1.Value = arrValuesInOrderOfBitLength[pIndex++]; /* simple code is just the value */
+ }
+ else
+ {
+ vHuft1.NumberOfExtraBits = arrExtraBitsForNonSimpleCodes[
+ arrValuesInOrderOfBitLength[pIndex] - numberOfSimpleValueCodes
+ ]; /* non-simple--look up in lists */
+ vHuft1.Value = arrBaseValuesForNonSimpleCodes[
+ arrValuesInOrderOfBitLength[pIndex++] - numberOfSimpleValueCodes
+ ];
+ }
+
+ /* fill code-like entries with r */
+ int fBitCounter2 = 1 << (numberOfBitsInCurrentCode - bitsBeforeThisTable);
+ for (
+ counter = counterCurrentCode >> bitsBeforeThisTable;
+ counter < numberOfEntriesInCurrentTable;
+ counter += fBitCounter2
+ )
+ pointerToCurrentTable[counter] = vHuft1;
+
+ /* backwards increment the k-bit code i */
+ for (
+ counter = 1 << (numberOfBitsInCurrentCode - 1);
+ (counterCurrentCode & counter) != 0;
+ counter >>= 1
+ )
+ counterCurrentCode ^= counter;
+ counterCurrentCode ^= counter;
+
+ /* backup over finished tables */
+ while (
+ (counterCurrentCode & ((1 << bitsBeforeThisTable) - 1)) != bitOffset[tableLevel]
+ )
+ bitsBeforeThisTable -= arrLX[stackOfBitsPerTable + (--tableLevel)];
+ }
+ }
+
+ /* return actual size of base table */
+ outBitsForTable = arrLX[stackOfBitsPerTable];
+
+ /* Return true (1) if we were given an incomplete table */
+ return (numberOfDummyCodesAdded != 0 && maximumCodeLength != 1) ? 1 : 0;
+ }
+}
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilter.cs b/src/SharpCompress/Compressors/Filters/BCJFilter.cs
index 83a93397..e7f00c98 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilter.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilter.cs
@@ -13,7 +13,7 @@ internal class BCJFilter : Filter
true,
false,
false,
- false
+ false,
};
private static readonly int[] MASK_TO_BIT_NUMBER = { 0, 1, 2, 2, 3, 3, 3, 3 };
diff --git a/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs b/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
index 07eaf319..44323ae7 100644
--- a/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
+++ b/src/SharpCompress/Compressors/Filters/BCJFilterIA64.cs
@@ -39,7 +39,7 @@ internal class BCJFilterIA64 : Filter
4,
4,
0,
- 0
+ 0,
};
public BCJFilterIA64(bool isEncoder, Stream baseStream)
diff --git a/src/SharpCompress/Compressors/LZMA/ICoder.cs b/src/SharpCompress/Compressors/LZMA/ICoder.cs
index dcddf929..95134979 100644
--- a/src/SharpCompress/Compressors/LZMA/ICoder.cs
+++ b/src/SharpCompress/Compressors/LZMA/ICoder.cs
@@ -147,7 +147,7 @@ internal enum CoderPropId
///
/// Specifies mode with end marker.
///
- EndMarker
+ EndMarker,
}
internal interface ISetCoderProperties
diff --git a/src/SharpCompress/Compressors/LZMA/LZipStream.cs b/src/SharpCompress/Compressors/LZMA/LZipStream.cs
index 5bb35a75..6570e908 100644
--- a/src/SharpCompress/Compressors/LZMA/LZipStream.cs
+++ b/src/SharpCompress/Compressors/LZMA/LZipStream.cs
@@ -201,8 +201,8 @@ public sealed class LZipStream : Stream
(byte)'I',
(byte)'P',
1,
- 113
- ];
+ 113,
+ };
public static void WriteHeaderSize(Stream stream) =>
// hard coding the dictionary size encoding
@@ -224,5 +224,5 @@ public sealed class LZipStream : Stream
(byte)((dictionarySize >> 8) & 0xff),
(byte)((dictionarySize >> 16) & 0xff),
(byte)((dictionarySize >> 24) & 0xff)
- ];
+ };
}
diff --git a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
index 0c2a91dc..e9fa1bab 100644
--- a/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
+++ b/src/SharpCompress/Compressors/LZMA/LzmaEncoder.cs
@@ -13,7 +13,7 @@ internal class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties
private enum EMatchFinderType
{
Bt2,
- Bt4
+ Bt4,
}
private const uint K_IFINITY_PRICE = 0xFFFFFFF;
diff --git a/src/SharpCompress/Compressors/LZMA/LzmaEncoderProperties.cs b/src/SharpCompress/Compressors/LZMA/LzmaEncoderProperties.cs
index 274e757b..198ba471 100644
--- a/src/SharpCompress/Compressors/LZMA/LzmaEncoderProperties.cs
+++ b/src/SharpCompress/Compressors/LZMA/LzmaEncoderProperties.cs
@@ -38,7 +38,7 @@ public class LzmaEncoderProperties
CoderPropId.Algorithm,
CoderPropId.NumFastBytes,
CoderPropId.MatchFinder,
- CoderPropId.EndMarker
+ CoderPropId.EndMarker,
};
_properties = new object[]
{
@@ -49,7 +49,7 @@ public class LzmaEncoderProperties
algorithm,
numFastBytes,
mf,
- eos
+ eos,
};
}
}
diff --git a/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs b/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs
index d4e91921..f02ec847 100644
--- a/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs
+++ b/src/SharpCompress/Compressors/PPMd/H/ModelPPM.cs
@@ -132,7 +132,7 @@ internal class ModelPpm
0x64A1,
0x5ABC,
0x6632,
- 0x6051
+ 0x6051,
};
// Temp fields
diff --git a/src/SharpCompress/Compressors/PPMd/I1/Model.cs b/src/SharpCompress/Compressors/PPMd/I1/Model.cs
index 9a1d090f..cd7f7ac4 100644
--- a/src/SharpCompress/Compressors/PPMd/I1/Model.cs
+++ b/src/SharpCompress/Compressors/PPMd/I1/Model.cs
@@ -59,7 +59,7 @@ internal partial class Model
0x64A1,
0x5ABC,
0x6632,
- 0x6051
+ 0x6051,
};
private static ReadOnlySpan EXPONENTIAL_ESCAPES =>
diff --git a/src/SharpCompress/Compressors/PPMd/I1/ModelRestorationMethod.cs b/src/SharpCompress/Compressors/PPMd/I1/ModelRestorationMethod.cs
index 0a504c99..9f4ccc43 100644
--- a/src/SharpCompress/Compressors/PPMd/I1/ModelRestorationMethod.cs
+++ b/src/SharpCompress/Compressors/PPMd/I1/ModelRestorationMethod.cs
@@ -24,5 +24,5 @@ internal enum ModelRestorationMethod
///
/// Freeze the context tree (in some cases may result in poor compression).
///
- Freeze = 2
+ Freeze = 2,
}
diff --git a/src/SharpCompress/Compressors/PPMd/PpmdVersion.cs b/src/SharpCompress/Compressors/PPMd/PpmdVersion.cs
index 791034ac..57626660 100644
--- a/src/SharpCompress/Compressors/PPMd/PpmdVersion.cs
+++ b/src/SharpCompress/Compressors/PPMd/PpmdVersion.cs
@@ -4,5 +4,5 @@ public enum PpmdVersion
{
H,
H7Z,
- I1
+ I1,
}
diff --git a/src/SharpCompress/Compressors/Rar/RarBLAKE2spStream.cs b/src/SharpCompress/Compressors/Rar/RarBLAKE2spStream.cs
index cf93cffb..0cf7c85c 100644
--- a/src/SharpCompress/Compressors/Rar/RarBLAKE2spStream.cs
+++ b/src/SharpCompress/Compressors/Rar/RarBLAKE2spStream.cs
@@ -27,7 +27,7 @@ internal class RarBLAKE2spStream : RarStream
0x510E527FU,
0x9B05688CU,
0x1F83D9ABU,
- 0x5BE0CD19U
+ 0x5BE0CD19U,
};
static readonly byte[][] k_BLAKE2S_Sigma =
diff --git a/src/SharpCompress/Compressors/Rar/RarCRC.cs b/src/SharpCompress/Compressors/Rar/RarCRC.cs
index 8f4fb47e..7e6fc6cc 100644
--- a/src/SharpCompress/Compressors/Rar/RarCRC.cs
+++ b/src/SharpCompress/Compressors/Rar/RarCRC.cs
@@ -9,7 +9,7 @@ internal static class RarCRC
public static uint CheckCrc(uint startCrc, byte b) =>
(crcTab[((int)startCrc ^ b) & 0xff] ^ (startCrc >> 8));
- public static uint CheckCrc(uint startCrc, byte[] data, int offset, int count)
+ public static uint CheckCrc(uint startCrc, ReadOnlySpan data, int offset, int count)
{
var size = Math.Min(data.Length - offset, count);
diff --git a/src/SharpCompress/Compressors/Rar/RarStream.cs b/src/SharpCompress/Compressors/Rar/RarStream.cs
index bf5d3209..073fcaa0 100644
--- a/src/SharpCompress/Compressors/Rar/RarStream.cs
+++ b/src/SharpCompress/Compressors/Rar/RarStream.cs
@@ -1,6 +1,7 @@
#nullable disable
using System;
+using System.Buffers;
using System.IO;
using SharpCompress.Common.Rar.Headers;
@@ -14,7 +15,7 @@ internal class RarStream : Stream
private bool fetch;
- private byte[] tmpBuffer = BufferPool.Rent(65536);
+ private byte[] tmpBuffer = ArrayPool.Shared.Rent(65536);
private int tmpOffset;
private int tmpCount;
@@ -42,7 +43,7 @@ internal class RarStream : Stream
{
if (disposing)
{
- BufferPool.Return(this.tmpBuffer);
+ ArrayPool.Shared.Return(this.tmpBuffer);
this.tmpBuffer = null;
}
isDisposed = true;
@@ -143,11 +144,11 @@ internal class RarStream : Stream
this.tmpBuffer.Length * 2 > this.tmpCount + count
? this.tmpBuffer.Length * 2
: this.tmpCount + count;
- var newBuffer = BufferPool.Rent(newLength);
+ var newBuffer = ArrayPool.Shared.Rent(newLength);
Buffer.BlockCopy(this.tmpBuffer, 0, newBuffer, 0, this.tmpCount);
var oldBuffer = this.tmpBuffer;
this.tmpBuffer = newBuffer;
- BufferPool.Return(oldBuffer);
+ ArrayPool.Shared.Return(oldBuffer);
}
}
}
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/CodeType.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/CodeType.cs
index 0ec7943d..67f24def 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/CodeType.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/CodeType.cs
@@ -10,5 +10,5 @@ internal enum CodeType
CODE_STARTFILE,
CODE_ENDFILE,
CODE_VM,
- CODE_VMDATA
+ CODE_VMDATA,
}
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/FilterType.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/FilterType.cs
index 67e38c45..d09fcc16 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/FilterType.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/Decode/FilterType.cs
@@ -12,5 +12,5 @@ internal enum FilterType : byte
FILTER_RGB,
FILTER_ITANIUM,
FILTER_PPM,
- FILTER_NONE
+ FILTER_NONE,
}
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/PPM/BlockTypes.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/PPM/BlockTypes.cs
index 3b4a9372..ded3c34b 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/PPM/BlockTypes.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/PPM/BlockTypes.cs
@@ -3,5 +3,5 @@ namespace SharpCompress.Compressors.Rar.UnpackV1.PPM;
internal enum BlockTypes
{
BLOCK_LZ = 0,
- BLOCK_PPM = 1
+ BLOCK_PPM = 1,
}
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.cs
index e6d4153d..c62d5906 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack.cs
@@ -1,6 +1,7 @@
#nullable disable
using System;
+using System.Buffers;
using System.Collections.Generic;
using System.IO;
using SharpCompress.Common;
@@ -12,14 +13,28 @@ using SharpCompress.Compressors.Rar.VM;
namespace SharpCompress.Compressors.Rar.UnpackV1;
-internal sealed partial class Unpack : BitInput, IRarUnpack
+internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
{
private readonly BitInput Inp;
+ private bool disposed;
public Unpack() =>
// to ease in porting Unpack50.cs
Inp = this;
+ public void Dispose()
+ {
+ if (!disposed)
+ {
+ if (!externalWindow)
+ {
+ ArrayPool.Shared.Return(window);
+ window = null;
+ }
+ disposed = true;
+ }
+ }
+
public bool FileExtracted { get; private set; }
public long DestSize
@@ -74,7 +89,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
private BlockTypes unpBlockType;
- //private bool externalWindow;
+ private bool externalWindow;
private long writtenFileSize;
@@ -104,22 +119,21 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
2,
14,
0,
- 12
+ 12,
};
private FileHeader fileHeader;
private void Init(byte[] window)
{
- if (window is null)
+ if (this.window is null && window is null)
{
- this.window = new byte[PackDef.MAXWINSIZE];
+ this.window = ArrayPool.Shared.Rent(PackDef.MAXWINSIZE);
}
- else
+ else if (window is not null)
{
this.window = window;
-
- //externalWindow = true;
+ externalWindow = true;
}
inAddr = 0;
UnpInitData(false);
@@ -175,31 +189,24 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
private void UnstoreFile()
{
- var buffer = new byte[0x10000];
- while (true)
+ Span buffer = stackalloc byte[(int)Math.Min(0x10000, destUnpSize)];
+ do
{
- var code = readStream.Read(buffer, 0, (int)Math.Min(buffer.Length, destUnpSize));
+ var code = readStream.Read(buffer);
if (code == 0 || code == -1)
{
break;
}
code = code < destUnpSize ? code : (int)destUnpSize;
- writeStream.Write(buffer, 0, code);
- if (destUnpSize >= 0)
- {
- destUnpSize -= code;
- }
- if (suspended)
- {
- return;
- }
- }
+ writeStream.Write(buffer.Slice(0, code));
+ destUnpSize -= code;
+ } while (!suspended && destUnpSize > 0);
}
private void Unpack29(bool solid)
{
- var DDecode = new int[PackDef.DC];
- var DBits = new byte[PackDef.DC];
+ Span DDecode = stackalloc int[PackDef.DC];
+ Span DBits = stackalloc byte[PackDef.DC];
int Bits;
@@ -859,9 +866,9 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
private bool ReadTables()
{
- var bitLength = new byte[PackDef.BC];
+ Span bitLength = stackalloc byte[PackDef.BC];
+ Span table = stackalloc byte[PackDef.HUFF_TABLE_SIZE];
- var table = new byte[PackDef.HUFF_TABLE_SIZE];
if (inAddr > readTop - 25)
{
if (!unpReadBuf())
@@ -989,7 +996,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
// memcpy(unpOldTable,table,sizeof(unpOldTable));
- Buffer.BlockCopy(table, 0, unpOldTable, 0, unpOldTable.Length);
+ table.CopyTo(unpOldTable);
return (true);
}
@@ -1190,7 +1197,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack
{
return (false);
}
- var VMCode = new byte[VMCodeSize];
+ Span VMCode = stackalloc byte[VMCodeSize];
for (var I = 0; I < VMCodeSize; I++)
{
if (Inp.Overflow(3))
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.cs
index 8513c24b..4c6e3894 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack15.cs
@@ -88,7 +88,7 @@ internal partial class Unpack
0xf000,
0xf200,
0xf200,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosL1 = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
@@ -106,7 +106,7 @@ internal partial class Unpack
0xf000,
0xf200,
0xf240,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosL2 = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
@@ -123,7 +123,7 @@ internal partial class Unpack
0xf200,
0xf200,
0xf200,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosHf0 = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33 };
@@ -139,7 +139,7 @@ internal partial class Unpack
0xf200,
0xf200,
0xf7e0,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosHf1 = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127 };
@@ -155,7 +155,7 @@ internal partial class Unpack
0xfa00,
0xffff,
0xffff,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosHf2 = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
@@ -170,7 +170,7 @@ internal partial class Unpack
0xfe80,
0xffff,
0xffff,
- 0xffff
+ 0xffff,
};
private static readonly int[] PosHf3 = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
@@ -199,7 +199,7 @@ internal partial class Unpack
0x90,
0x98,
0x9c,
- 0xb0
+ 0xb0,
};
private static readonly int[] ShortLen2 = { 2, 3, 3, 3, 4, 4, 5, 6, 6, 4, 4, 5, 6, 6, 4, 0 };
@@ -220,7 +220,7 @@ internal partial class Unpack
0x90,
0x98,
0x9c,
- 0xb0
+ 0xb0,
};
private void unpack15(bool solid)
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack20.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack20.cs
index 3a5d008d..809aaf60 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack20.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/Unpack20.cs
@@ -64,7 +64,7 @@ internal partial class Unpack
128,
160,
192,
- 224
+ 224,
};
private static ReadOnlySpan LBits =>
@@ -97,7 +97,7 @@ internal partial class Unpack
5,
5,
5,
- 5
+ 5,
};
private static readonly int[] DDecode =
@@ -149,7 +149,7 @@ internal partial class Unpack
786432,
851968,
917504,
- 983040
+ 983040,
};
private static readonly int[] DBits =
@@ -201,7 +201,7 @@ internal partial class Unpack
16,
16,
16,
- 16
+ 16,
};
private static readonly int[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
@@ -391,8 +391,8 @@ internal partial class Unpack
private bool ReadTables20()
{
- var BitLength = new byte[PackDef.BC20];
- var Table = new byte[PackDef.MC20 * 4];
+ Span BitLength = stackalloc byte[PackDef.BC20];
+ Span Table = stackalloc byte[PackDef.MC20 * 4];
int TableSize,
N,
I;
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV1/UnpackUtility.cs b/src/SharpCompress/Compressors/Rar/UnpackV1/UnpackUtility.cs
index b501337b..4b16e43d 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV1/UnpackUtility.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV1/UnpackUtility.cs
@@ -181,7 +181,12 @@ internal static class UnpackUtility
return (dec.DecodeNum[N]);
}
- internal static void makeDecodeTables(byte[] lenTab, int offset, Decode.Decode dec, int size)
+ internal static void makeDecodeTables(
+ Span lenTab,
+ int offset,
+ Decode.Decode dec,
+ int size
+ )
{
Span lenCount = stackalloc int[16];
Span tmpPos = stackalloc int[16];
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack15_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack15_cpp.cs
index dabb0e08..c1886df8 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack15_cpp.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack15_cpp.cs
@@ -19,7 +19,7 @@ internal partial class Unpack
0xf000,
0xf200,
0xf200,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosL1 = { 0, 0, 0, 2, 3, 5, 7, 11, 16, 20, 24, 32, 32 };
@@ -37,7 +37,7 @@ internal partial class Unpack
0xf000,
0xf200,
0xf240,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosL2 = { 0, 0, 0, 0, 5, 7, 9, 13, 18, 22, 26, 34, 36 };
@@ -54,7 +54,7 @@ internal partial class Unpack
0xf200,
0xf200,
0xf200,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosHf0 = { 0, 0, 0, 0, 0, 8, 16, 24, 33, 33, 33, 33, 33 };
@@ -70,7 +70,7 @@ internal partial class Unpack
0xf200,
0xf200,
0xf7e0,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosHf1 = { 0, 0, 0, 0, 0, 0, 4, 44, 60, 76, 80, 80, 127 };
@@ -86,7 +86,7 @@ internal partial class Unpack
0xfa00,
0xffff,
0xffff,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosHf2 = { 0, 0, 0, 0, 0, 0, 2, 7, 53, 117, 233, 0, 0 };
@@ -101,7 +101,7 @@ internal partial class Unpack
0xfe80,
0xffff,
0xffff,
- 0xffff
+ 0xffff,
};
private static readonly uint[] PosHf3 = { 0, 0, 0, 0, 0, 0, 0, 2, 16, 218, 251, 0, 0 };
@@ -225,7 +225,7 @@ internal partial class Unpack
6,
6,
4,
- 0
+ 0,
};
public static readonly uint[] ShortXor1 =
{
@@ -243,7 +243,7 @@ internal partial class Unpack
0x90,
0x98,
0x9c,
- 0xb0
+ 0xb0,
};
public static readonly uint[] ShortLen2 =
{
@@ -262,7 +262,7 @@ internal partial class Unpack
6,
6,
4,
- 0
+ 0,
};
public static readonly uint[] ShortXor2 =
{
@@ -280,7 +280,7 @@ internal partial class Unpack
0x90,
0x98,
0x9c,
- 0xb0
+ 0xb0,
};
}
diff --git a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs
index 51dbff0b..d3125727 100644
--- a/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs
+++ b/src/SharpCompress/Compressors/Rar/UnpackV2017/Unpack.unpack20_cpp.cs
@@ -53,7 +53,7 @@ internal partial class Unpack
128,
160,
192,
- 224
+ 224,
};
public static readonly byte[] LBits =
{
@@ -84,7 +84,7 @@ internal partial class Unpack
5,
5,
5,
- 5
+ 5,
};
public static readonly uint[] DDecode =
{
@@ -135,7 +135,7 @@ internal partial class Unpack
786432,
851968,
917504,
- 983040
+ 983040,
};
public static readonly byte[] DBits =
{
@@ -186,7 +186,7 @@ internal partial class Unpack
16,
16,
16,
- 16
+ 16,
};
public static readonly byte[] SDDecode = { 0, 4, 8, 16, 32, 64, 128, 192 };
public static readonly byte[] SDBits = { 2, 2, 3, 4, 5, 6, 6, 6 };
diff --git a/src/SharpCompress/Compressors/Rar/VM/RarVM.cs b/src/SharpCompress/Compressors/Rar/VM/RarVM.cs
index f758b8a4..f1ef3834 100644
--- a/src/SharpCompress/Compressors/Rar/VM/RarVM.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/RarVM.cs
@@ -776,14 +776,14 @@ internal sealed class RarVM : BitInput
}
}
- public void prepare(byte[] code, int codeSize, VMPreparedProgram prg)
+ public void prepare(ReadOnlySpan code, int codeSize, VMPreparedProgram prg)
{
InitBitInput();
var cpLength = Math.Min(MAX_SIZE, codeSize);
// memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
- Buffer.BlockCopy(code, 0, InBuf, 0, cpLength);
+ code.Slice(0, cpLength).CopyTo(InBuf);
byte xorSum = 0;
for (var i = 1; i < codeSize; i++)
{
@@ -1105,7 +1105,7 @@ internal sealed class RarVM : BitInput
}
}
- private VMStandardFilters IsStandardFilter(byte[] code, int codeSize)
+ private VMStandardFilters IsStandardFilter(ReadOnlySpan code, int codeSize)
{
VMStandardFilterSignature[] stdList =
{
@@ -1115,7 +1115,7 @@ internal sealed class RarVM : BitInput
new(29, 0x0e06077d, VMStandardFilters.VMSF_DELTA),
new(149, 0x1c2c5dc8, VMStandardFilters.VMSF_RGB),
new(216, 0xbc85e701, VMStandardFilters.VMSF_AUDIO),
- new(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE)
+ new(40, 0x46b9c560, VMStandardFilters.VMSF_UPCASE),
};
var CodeCRC = RarCRC.CheckCrc(0xffffffff, code, 0, code.Length) ^ 0xffffffff;
for (var i = 0; i < stdList.Length; i++)
diff --git a/src/SharpCompress/Compressors/Rar/VM/VMCmdFlags.cs b/src/SharpCompress/Compressors/Rar/VM/VMCmdFlags.cs
index 00de0b6a..9dbafe1b 100644
--- a/src/SharpCompress/Compressors/Rar/VM/VMCmdFlags.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/VMCmdFlags.cs
@@ -53,6 +53,6 @@ internal class VMCmdFlags
VMCF_OP2 | VMCF_BYTEMODE,
VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS,
VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS,
- VMCF_OP0
+ VMCF_OP0,
};
}
diff --git a/src/SharpCompress/Compressors/Rar/VM/VMCommands.cs b/src/SharpCompress/Compressors/Rar/VM/VMCommands.cs
index 7bb1a396..a10eb072 100644
--- a/src/SharpCompress/Compressors/Rar/VM/VMCommands.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/VMCommands.cs
@@ -66,5 +66,5 @@ internal enum VMCommands
VM_NEGB = 52,
VM_NEGD = 53,
- VM_STANDARD = 54
+ VM_STANDARD = 54,
}
diff --git a/src/SharpCompress/Compressors/Rar/VM/VMFlags.cs b/src/SharpCompress/Compressors/Rar/VM/VMFlags.cs
index fa9a72e7..12765775 100644
--- a/src/SharpCompress/Compressors/Rar/VM/VMFlags.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/VMFlags.cs
@@ -5,5 +5,5 @@ internal enum VMFlags
None = 0,
VM_FC = 1,
VM_FZ = 2,
- VM_FS = 80000000
+ VM_FS = 80000000,
}
diff --git a/src/SharpCompress/Compressors/Rar/VM/VMOpType.cs b/src/SharpCompress/Compressors/Rar/VM/VMOpType.cs
index bcc4214e..77994746 100644
--- a/src/SharpCompress/Compressors/Rar/VM/VMOpType.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/VMOpType.cs
@@ -5,5 +5,5 @@ internal enum VMOpType
VM_OPREG = 0,
VM_OPINT = 1,
VM_OPREGMEM = 2,
- VM_OPNONE = 3
+ VM_OPNONE = 3,
}
diff --git a/src/SharpCompress/Compressors/Rar/VM/VMStandardFilters.cs b/src/SharpCompress/Compressors/Rar/VM/VMStandardFilters.cs
index 4b90b019..2c435ebb 100644
--- a/src/SharpCompress/Compressors/Rar/VM/VMStandardFilters.cs
+++ b/src/SharpCompress/Compressors/Rar/VM/VMStandardFilters.cs
@@ -9,5 +9,5 @@ internal enum VMStandardFilters
VMSF_RGB = 4,
VMSF_AUDIO = 5,
VMSF_DELTA = 6,
- VMSF_UPCASE = 7
+ VMSF_UPCASE = 7,
}
diff --git a/src/SharpCompress/Compressors/Reduce/ReduceStream.cs b/src/SharpCompress/Compressors/Reduce/ReduceStream.cs
new file mode 100644
index 00000000..1cb67f44
--- /dev/null
+++ b/src/SharpCompress/Compressors/Reduce/ReduceStream.cs
@@ -0,0 +1,249 @@
+using System;
+using System.IO;
+
+namespace SharpCompress.Compressors.Reduce;
+
+public class ReduceStream : Stream
+{
+ private readonly long unCompressedSize;
+ private readonly long compressedSize;
+ private readonly Stream inStream;
+
+ private long inByteCount;
+ private const int EOF = 1234;
+
+ private readonly int factor;
+ private readonly int distanceMask;
+ private readonly int lengthMask;
+
+ private long outBytesCount;
+
+ private readonly byte[] windowsBuffer;
+ private int windowIndex;
+ private int length;
+ private int distance;
+
+ public ReduceStream(Stream inStr, long compsize, long unCompSize, int factor)
+ {
+ inStream = inStr;
+ compressedSize = compsize;
+ unCompressedSize = unCompSize;
+ inByteCount = 0;
+ outBytesCount = 0;
+
+ this.factor = factor;
+ distanceMask = (int)mask_bits[factor] << 8;
+ lengthMask = 0xff >> factor;
+
+ windowIndex = 0;
+ length = 0;
+ distance = 0;
+
+ windowsBuffer = new byte[WSIZE];
+
+ outByte = 0;
+
+ LoadBitLengthTable();
+ LoadNextByteTable();
+ }
+
+ public override void Flush()
+ {
+ throw new NotImplementedException();
+ }
+
+ public override long Seek(long offset, SeekOrigin origin)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void SetLength(long value)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override void Write(byte[] buffer, int offset, int count)
+ {
+ throw new NotImplementedException();
+ }
+
+ public override bool CanRead => true;
+ public override bool CanSeek => false;
+ public override bool CanWrite => false;
+ public override long Length => unCompressedSize;
+ public override long Position
+ {
+ get => outBytesCount;
+ set { }
+ }
+
+ private const int RunLengthCode = 144;
+ private const int WSIZE = 0x4000;
+
+ private readonly uint[] mask_bits = new uint[]
+ {
+ 0x0000,
+ 0x0001,
+ 0x0003,
+ 0x0007,
+ 0x000f,
+ 0x001f,
+ 0x003f,
+ 0x007f,
+ 0x00ff,
+ 0x01ff,
+ 0x03ff,
+ 0x07ff,
+ 0x0fff,
+ 0x1fff,
+ 0x3fff,
+ 0x7fff,
+ 0xffff,
+ };
+
+ private int bitBufferCount;
+ private ulong bitBuffer;
+
+ private int NEXTBYTE()
+ {
+ if (inByteCount == compressedSize)
+ return EOF;
+ inByteCount++;
+ return inStream.ReadByte();
+ }
+
+ private void READBITS(int nbits, out byte zdest)
+ {
+ if (nbits > bitBufferCount)
+ {
+ int temp;
+ while (bitBufferCount <= 8 * (int)(4 - 1) && (temp = NEXTBYTE()) != EOF)
+ {
+ bitBuffer |= (ulong)temp << bitBufferCount;
+ bitBufferCount += 8;
+ }
+ }
+ zdest = (byte)(bitBuffer & (ulong)mask_bits[nbits]);
+ bitBuffer >>= nbits;
+ bitBufferCount -= nbits;
+ }
+
+ private byte[] bitCountTable = [];
+
+ private void LoadBitLengthTable()
+ {
+ byte[] bitPos = { 0, 2, 4, 8, 16, 32, 64, 128, 255 };
+ bitCountTable = new byte[256];
+
+ for (byte i = 1; i <= 8; i++)
+ {
+ int vMin = bitPos[i - 1] + 1;
+ int vMax = bitPos[i];
+ for (int j = vMin; j <= vMax; j++)
+ {
+ bitCountTable[j] = i;
+ }
+ }
+ }
+
+ private byte[][] nextByteTable = [];
+
+ private void LoadNextByteTable()
+ {
+ nextByteTable = new byte[256][];
+ for (int x = 255; x >= 0; x--)
+ {
+ READBITS(6, out byte Slen);
+ nextByteTable[x] = new byte[Slen];
+ for (int i = 0; i < Slen; i++)
+ {
+ READBITS(8, out nextByteTable[x][i]);
+ }
+ }
+ }
+
+ private byte outByte;
+
+ private byte GetNextByte()
+ {
+ if (nextByteTable[outByte].Length == 0)
+ {
+ READBITS(8, out outByte);
+ return outByte;
+ }
+ READBITS(1, out byte nextBit);
+ if (nextBit == 1)
+ {
+ READBITS(8, out outByte);
+ return outByte;
+ }
+ READBITS(bitCountTable[nextByteTable[outByte].Length], out byte nextByteIndex);
+ outByte = nextByteTable[outByte][nextByteIndex];
+ return outByte;
+ }
+
+ public override int Read(byte[] buffer, int offset, int count)
+ {
+ int countIndex = 0;
+ while (countIndex < count && outBytesCount < unCompressedSize)
+ {
+ if (length == 0)
+ {
+ byte nextByte = GetNextByte();
+ if (nextByte != RunLengthCode)
+ {
+ buffer[offset + (countIndex++)] = nextByte;
+ windowsBuffer[windowIndex++] = nextByte;
+ outBytesCount++;
+ if (windowIndex == WSIZE)
+ windowIndex = 0;
+
+ continue;
+ }
+
+ nextByte = GetNextByte();
+ if (nextByte == 0)
+ {
+ buffer[offset + (countIndex++)] = RunLengthCode;
+ windowsBuffer[windowIndex++] = RunLengthCode;
+ outBytesCount++;
+ if (windowIndex == WSIZE)
+ windowIndex = 0;
+
+ continue;
+ }
+
+ int lengthDistanceByte = nextByte;
+ length = lengthDistanceByte & lengthMask;
+ if (length == lengthMask)
+ {
+ length += GetNextByte();
+ }
+ length += 3;
+
+ int distanceHighByte = (lengthDistanceByte << factor) & distanceMask;
+ distance = windowIndex - (distanceHighByte + GetNextByte() + 1);
+
+ distance &= WSIZE - 1;
+ }
+
+ while (length != 0 && countIndex < count)
+ {
+ byte nextByte = windowsBuffer[distance++];
+ buffer[offset + (countIndex++)] = nextByte;
+ windowsBuffer[windowIndex++] = nextByte;
+ outBytesCount++;
+
+ if (distance == WSIZE)
+ distance = 0;
+
+ if (windowIndex == WSIZE)
+ windowIndex = 0;
+
+ length--;
+ }
+ }
+
+ return countIndex;
+ }
+}
diff --git a/src/SharpCompress/Compressors/Shrink/BitStream.cs b/src/SharpCompress/Compressors/Shrink/BitStream.cs
index 9dc534e0..8bb69ead 100644
--- a/src/SharpCompress/Compressors/Shrink/BitStream.cs
+++ b/src/SharpCompress/Compressors/Shrink/BitStream.cs
@@ -26,7 +26,7 @@ namespace SharpCompress.Compressors.Shrink
8191U,
16383U,
(uint)short.MaxValue,
- (uint)ushort.MaxValue
+ (uint)ushort.MaxValue,
};
public BitStream(byte[] src, int srcLen)
diff --git a/src/SharpCompress/Compressors/Shrink/HwUnshrink.cs b/src/SharpCompress/Compressors/Shrink/HwUnshrink.cs
index 6ad5ab7c..4506ccb1 100644
--- a/src/SharpCompress/Compressors/Shrink/HwUnshrink.cs
+++ b/src/SharpCompress/Compressors/Shrink/HwUnshrink.cs
@@ -387,7 +387,7 @@ namespace SharpCompress.Compressors.Shrink
{
Ok,
Full,
- Error
+ Error,
}
private struct CodeQueue
diff --git a/src/SharpCompress/Compressors/Xz/CheckType.cs b/src/SharpCompress/Compressors/Xz/CheckType.cs
index a94f8261..4c4fafcd 100644
--- a/src/SharpCompress/Compressors/Xz/CheckType.cs
+++ b/src/SharpCompress/Compressors/Xz/CheckType.cs
@@ -5,5 +5,5 @@ public enum CheckType : byte
NONE = 0x00,
CRC32 = 0x01,
CRC64 = 0x04,
- SHA256 = 0x0A
+ SHA256 = 0x0A,
}
diff --git a/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs b/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs
index a7e3482a..eba9b1ac 100644
--- a/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs
+++ b/src/SharpCompress/Compressors/Xz/Filters/BlockFilter.cs
@@ -16,20 +16,19 @@ public abstract class BlockFilter : ReadOnlyStream
ArchArmFilter = 0x07,
ArchArmThumbFilter = 0x08,
ArchSparcFilter = 0x09,
- Lzma2 = 0x21
+ Lzma2 = 0x21,
}
- private static readonly Dictionary> FILTER_MAP =
- new()
- {
- { FilterTypes.ArchX86Filter, () => new X86Filter() },
- { FilterTypes.ArchPowerPcFilter, () => new PowerPCFilter() },
- { FilterTypes.ArchIa64Filter, () => new IA64Filter() },
- { FilterTypes.ArchArmFilter, () => new ArmFilter() },
- { FilterTypes.ArchArmThumbFilter, () => new ArmThumbFilter() },
- { FilterTypes.ArchSparcFilter, () => new SparcFilter() },
- { FilterTypes.Lzma2, () => new Lzma2Filter() }
- };
+ private static readonly Dictionary> FILTER_MAP = new()
+ {
+ { FilterTypes.ArchX86Filter, () => new X86Filter() },
+ { FilterTypes.ArchPowerPcFilter, () => new PowerPCFilter() },
+ { FilterTypes.ArchIa64Filter, () => new IA64Filter() },
+ { FilterTypes.ArchArmFilter, () => new ArmFilter() },
+ { FilterTypes.ArchArmThumbFilter, () => new ArmThumbFilter() },
+ { FilterTypes.ArchSparcFilter, () => new SparcFilter() },
+ { FilterTypes.Lzma2, () => new Lzma2Filter() },
+ };
public abstract bool AllowAsLast { get; }
public abstract bool AllowAsNonLast { get; }
diff --git a/src/SharpCompress/Compressors/Xz/XZBlock.cs b/src/SharpCompress/Compressors/Xz/XZBlock.cs
index 34ce2333..cdb075ef 100644
--- a/src/SharpCompress/Compressors/Xz/XZBlock.cs
+++ b/src/SharpCompress/Compressors/Xz/XZBlock.cs
@@ -26,13 +26,14 @@ public sealed class XZBlock : XZReadOnlyStream
private bool _endOfStream;
private bool _paddingSkipped;
private bool _crcChecked;
- private ulong _bytesRead;
+ private readonly long _startPosition;
public XZBlock(Stream stream, CheckType checkType, int checkSize)
: base(stream)
{
_checkType = checkType;
_checkSize = checkSize;
+ _startPosition = stream.Position;
}
public override int Read(byte[] buffer, int offset, int count)
@@ -68,13 +69,12 @@ public sealed class XZBlock : XZReadOnlyStream
CheckCrc();
}
- _bytesRead += (ulong)bytesRead;
return bytesRead;
}
private void SkipPadding()
{
- var bytes = (int)(BaseStream.Position % 4);
+ var bytes = (BaseStream.Position - _startPosition) % 4;
if (bytes > 0)
{
var paddingBytes = new byte[4 - bytes];
diff --git a/src/SharpCompress/IO/StreamingMode.cs b/src/SharpCompress/IO/StreamingMode.cs
index 0fdb674d..33f7d236 100644
--- a/src/SharpCompress/IO/StreamingMode.cs
+++ b/src/SharpCompress/IO/StreamingMode.cs
@@ -3,5 +3,5 @@ namespace SharpCompress.IO;
public enum StreamingMode
{
Streaming,
- Seekable
+ Seekable,
}
diff --git a/src/SharpCompress/LazyReadOnlyCollection.cs b/src/SharpCompress/LazyReadOnlyCollection.cs
index cc9cb3fd..9c1b35eb 100644
--- a/src/SharpCompress/LazyReadOnlyCollection.cs
+++ b/src/SharpCompress/LazyReadOnlyCollection.cs
@@ -4,7 +4,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
-namespace SharpCompress;
+namespace SharpCompress.Helpers;
internal sealed class LazyReadOnlyCollection : ICollection
{
diff --git a/src/SharpCompress/NotNullExtensions.cs b/src/SharpCompress/NotNullExtensions.cs
index 956a4fde..2245612e 100644
--- a/src/SharpCompress/NotNullExtensions.cs
+++ b/src/SharpCompress/NotNullExtensions.cs
@@ -4,9 +4,9 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
-namespace SharpCompress;
+namespace SharpCompress.Helpers;
-public static class NotNullExtensions
+internal static class NotNullExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static IEnumerable Empty(this IEnumerable? source) =>
diff --git a/src/SharpCompress/ReadOnlyCollection.cs b/src/SharpCompress/ReadOnlyCollection.cs
deleted file mode 100644
index 745a59aa..00000000
--- a/src/SharpCompress/ReadOnlyCollection.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace SharpCompress;
-
-public class ReadOnlyCollection : ICollection
-{
- private readonly ICollection collection;
-
- public ReadOnlyCollection(ICollection collection) => this.collection = collection;
-
- public void Add(T item) => throw new NotSupportedException();
-
- public void Clear() => throw new NotSupportedException();
-
- public bool Contains(T item) => collection.Contains(item);
-
- public void CopyTo(T[] array, int arrayIndex) => collection.CopyTo(array, arrayIndex);
-
- public int Count => collection.Count;
-
- public bool IsReadOnly => true;
-
- public bool Remove(T item) => throw new NotSupportedException();
-
- public IEnumerator GetEnumerator() => collection.GetEnumerator();
-
- IEnumerator IEnumerable.GetEnumerator() => throw new NotSupportedException();
-}
diff --git a/src/SharpCompress/Readers/AbstractReader.cs b/src/SharpCompress/Readers/AbstractReader.cs
index da6279a9..ac4e1784 100644
--- a/src/SharpCompress/Readers/AbstractReader.cs
+++ b/src/SharpCompress/Readers/AbstractReader.cs
@@ -44,7 +44,7 @@ public abstract class AbstractReader : IReader, IReaderExtracti
#region IDisposable Members
- public void Dispose()
+ public virtual void Dispose()
{
_entriesForCurrentReadStream?.Dispose();
Volume?.Dispose();
diff --git a/src/SharpCompress/Readers/Rar/RarReader.cs b/src/SharpCompress/Readers/Rar/RarReader.cs
index 245001e3..aa73e30f 100644
--- a/src/SharpCompress/Readers/Rar/RarReader.cs
+++ b/src/SharpCompress/Readers/Rar/RarReader.cs
@@ -13,6 +13,7 @@ namespace SharpCompress.Readers.Rar;
///
public abstract class RarReader : AbstractReader
{
+ private bool _disposed;
private RarVolume? volume;
private Lazy UnpackV2017 { get; } =
new(() => new Compressors.Rar.UnpackV2017.Unpack());
@@ -21,6 +22,20 @@ public abstract class RarReader : AbstractReader
internal RarReader(ReaderOptions options)
: base(options, ArchiveType.Rar) { }
+ public override void Dispose()
+ {
+ if (!_disposed)
+ {
+ if (UnpackV1.IsValueCreated && UnpackV1.Value is IDisposable unpackV1)
+ {
+ unpackV1.Dispose();
+ }
+
+ _disposed = true;
+ base.Dispose();
+ }
+ }
+
protected abstract void ValidateArchive(RarVolume archive);
public override RarVolume? Volume => volume;
diff --git a/src/SharpCompress/Readers/Tar/TarReader.cs b/src/SharpCompress/Readers/Tar/TarReader.cs
index a686dc11..46493446 100644
--- a/src/SharpCompress/Readers/Tar/TarReader.cs
+++ b/src/SharpCompress/Readers/Tar/TarReader.cs
@@ -39,7 +39,7 @@ public class TarReader : AbstractReader
CompressionType.Xz => new XZStream(stream),
CompressionType.Lzw => new LzwStream(stream),
CompressionType.None => stream,
- _ => throw new NotSupportedException("Invalid compression type: " + compressionType)
+ _ => throw new NotSupportedException("Invalid compression type: " + compressionType),
};
}
diff --git a/src/SharpCompress/SharpCompress.csproj b/src/SharpCompress/SharpCompress.csproj
index a21d1726..b1397310 100644
--- a/src/SharpCompress/SharpCompress.csproj
+++ b/src/SharpCompress/SharpCompress.csproj
@@ -2,11 +2,11 @@
SharpCompress - Pure C# Decompression/Compression
en-US
- 0.37.0
- 0.37.0
- 0.37.0
+ 0.39.0
+ 0.39.0
+ 0.39.0
Adam Hathcock
- net462;netstandard2.0;netstandard2.1;net6.0;net8.0
+ net48;net481;netstandard2.0;net6.0;net8.0
SharpCompress
../../SharpCompress.snk
true
@@ -14,34 +14,32 @@
rar;unrar;zip;unzip;bzip2;gzip;tar;7zip;lzip;xz
https://github.com/adamhathcock/sharpcompress
MIT
- Copyright (c) 2014 Adam Hathcock
+ Copyright (c) 2025 Adam Hathcock
false
false
- SharpCompress is a compression library for NET Standard 2.0/NET Standard 2.1/NET 6.0/NET 8.0 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.
+ SharpCompress is a compression library for NET Standard 2.0/NET 4.8/NET 4.8.1/NET 6.0/NET 8.0 that can unrar, decompress 7zip, decompress xz, zip/unzip, tar/untar lzip/unlzip, bzip2/unbzip2 and gzip/ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.
true
true
snupkg
- true
latest
true
README.md
+ true
+ true
+ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
-
-
-
+
+ true
+
+
+
-
-
-
-
+
+
-
-
-
-
diff --git a/src/SharpCompress/Utility.cs b/src/SharpCompress/Utility.cs
index bcecafb4..74974850 100644
--- a/src/SharpCompress/Utility.cs
+++ b/src/SharpCompress/Utility.cs
@@ -1,15 +1,17 @@
+global using SharpCompress.Helpers;
using System;
using System.Buffers;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using System.IO;
+using System.Text;
using SharpCompress.Readers;
-namespace SharpCompress;
+namespace SharpCompress.Helpers;
-[CLSCompliant(false)]
-public static class Utility
+internal static class Utility
{
- public static ReadOnlyCollection ToReadOnly(this ICollection items) => new(items);
+ public static ReadOnlyCollection ToReadOnly(this IList items) => new(items);
///
/// Performs an unsigned bitwise right shift with the specified number
@@ -434,4 +436,17 @@ public static class Utility
buffer[offset + 2] = (byte)(number >> 8);
buffer[offset + 3] = (byte)number;
}
+
+ public static string ReplaceInvalidFileNameChars(string fileName)
+ {
+ var invalidChars = new HashSet(Path.GetInvalidFileNameChars());
+ var sb = new StringBuilder(fileName.Length);
+ foreach (var c in fileName)
+ {
+ var newChar = invalidChars.Contains(c) ? '_' : c;
+ sb.Append(newChar);
+ }
+
+ return sb.ToString();
+ }
}
diff --git a/src/SharpCompress/Writers/Zip/ZipWriter.cs b/src/SharpCompress/Writers/Zip/ZipWriter.cs
index 1fb66a2b..8e89da64 100644
--- a/src/SharpCompress/Writers/Zip/ZipWriter.cs
+++ b/src/SharpCompress/Writers/Zip/ZipWriter.cs
@@ -69,7 +69,7 @@ public class ZipWriter : AbstractWriter
CompressionType.BZip2 => ZipCompressionMethod.BZip2,
CompressionType.LZMA => ZipCompressionMethod.LZMA,
CompressionType.PPMd => ZipCompressionMethod.PPMd,
- _ => throw new InvalidFormatException("Invalid compression method: " + compressionType)
+ _ => throw new InvalidFormatException("Invalid compression method: " + compressionType),
};
public override void Write(string entryPath, Stream source, DateTime? modificationTime) =>
@@ -100,7 +100,7 @@ public class ZipWriter : AbstractWriter
)
{
Comment = options.EntryComment,
- ModificationTime = options.ModificationDateTime
+ ModificationTime = options.ModificationDateTime,
};
// Use the archive default setting for zip64 and allow overrides
diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json
index e6e0a13d..de18ff8d 100644
--- a/src/SharpCompress/packages.lock.json
+++ b/src/SharpCompress/packages.lock.json
@@ -1,16 +1,7 @@
{
"version": 2,
"dependencies": {
- ".NETFramework,Version=v4.6.2": {
- "Microsoft.NETFramework.ReferenceAssemblies": {
- "type": "Direct",
- "requested": "[1.0.3, )",
- "resolved": "1.0.3",
- "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
- "dependencies": {
- "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3"
- }
- },
+ ".NETFramework,Version=v4.8": {
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -21,43 +12,21 @@
"Microsoft.SourceLink.Common": "8.0.0"
}
},
- "System.Memory": {
+ "System.Buffers": {
"type": "Direct",
- "requested": "[4.5.5, )",
- "resolved": "4.5.5",
- "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
- "dependencies": {
- "System.Buffers": "4.5.1",
- "System.Numerics.Vectors": "4.5.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.3"
- }
- },
- "System.Text.Encoding.CodePages": {
- "type": "Direct",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
- "dependencies": {
- "System.Memory": "4.5.5",
- "System.Runtime.CompilerServices.Unsafe": "6.0.0"
- }
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
},
"ZstdSharp.Port": {
"type": "Direct",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA==",
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
- "System.Memory": "4.5.5"
- }
- },
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
- "dependencies": {
- "System.Threading.Tasks.Extensions": "4.5.4"
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"Microsoft.Build.Tasks.Git": {
@@ -65,21 +34,11 @@
"resolved": "8.0.0",
"contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
},
- "Microsoft.NETFramework.ReferenceAssemblies.net462": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ=="
- },
"Microsoft.SourceLink.Common": {
"type": "Transitive",
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
- "System.Buffers": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
- },
"System.Numerics.Vectors": {
"type": "Transitive",
"resolved": "4.5.0",
@@ -97,9 +56,129 @@
"dependencies": {
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
+ },
+ "Microsoft.Bcl.AsyncInterfaces": {
+ "type": "CentralTransitive",
+ "requested": "[8.0.0, )",
+ "resolved": "5.0.0",
+ "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "System.Memory": {
+ "type": "CentralTransitive",
+ "requested": "[4.6.0, )",
+ "resolved": "4.5.5",
+ "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ }
+ },
+ ".NETFramework,Version=v4.8.1": {
+ "Microsoft.NETFramework.ReferenceAssemblies": {
+ "type": "Direct",
+ "requested": "[1.0.3, )",
+ "resolved": "1.0.3",
+ "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
+ "dependencies": {
+ "Microsoft.NETFramework.ReferenceAssemblies.net481": "1.0.3"
+ }
+ },
+ "Microsoft.SourceLink.GitHub": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "8.0.0",
+ "Microsoft.SourceLink.Common": "8.0.0"
+ }
+ },
+ "System.Buffers": {
+ "type": "Direct",
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
+ },
+ "ZstdSharp.Port": {
+ "type": "Direct",
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
+ "dependencies": {
+ "Microsoft.Bcl.AsyncInterfaces": "5.0.0",
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
+ }
+ },
+ "Microsoft.Build.Tasks.Git": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
+ },
+ "Microsoft.NETFramework.ReferenceAssemblies.net481": {
+ "type": "Transitive",
+ "resolved": "1.0.3",
+ "contentHash": "Vv/20vgHS7VglVOVh8J3Iz/MA+VYKVRp9f7r2qiKBMuzviTOmocG70yq0Q8T5OTmCONkEAIJwETD1zhEfLkAXQ=="
+ },
+ "Microsoft.SourceLink.Common": {
+ "type": "Transitive",
+ "resolved": "8.0.0",
+ "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
+ },
+ "System.Numerics.Vectors": {
+ "type": "Transitive",
+ "resolved": "4.5.0",
+ "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ=="
+ },
+ "System.Runtime.CompilerServices.Unsafe": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
+ },
+ "System.Threading.Tasks.Extensions": {
+ "type": "Transitive",
+ "resolved": "4.5.4",
+ "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==",
+ "dependencies": {
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
+ },
+ "Microsoft.Bcl.AsyncInterfaces": {
+ "type": "CentralTransitive",
+ "requested": "[8.0.0, )",
+ "resolved": "5.0.0",
+ "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
+ "System.Memory": {
+ "type": "CentralTransitive",
+ "requested": "[4.6.0, )",
+ "resolved": "4.5.5",
+ "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "dependencies": {
+ "System.Buffers": "4.5.1",
+ "System.Numerics.Vectors": "4.5.0",
+ "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ }
}
},
".NETStandard,Version=v2.0": {
+ "Microsoft.Bcl.AsyncInterfaces": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==",
+ "dependencies": {
+ "System.Threading.Tasks.Extensions": "4.5.4"
+ }
+ },
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -119,15 +198,21 @@
"Microsoft.NETCore.Platforms": "1.1.0"
}
},
+ "System.Buffers": {
+ "type": "Direct",
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
+ },
"System.Memory": {
"type": "Direct",
- "requested": "[4.5.5, )",
- "resolved": "4.5.5",
- "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg==",
"dependencies": {
- "System.Buffers": "4.5.1",
- "System.Numerics.Vectors": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.3"
+ "System.Buffers": "4.6.0",
+ "System.Numerics.Vectors": "4.6.0",
+ "System.Runtime.CompilerServices.Unsafe": "6.1.0"
}
},
"System.Text.Encoding.CodePages": {
@@ -142,20 +227,13 @@
},
"ZstdSharp.Port": {
"type": "Direct",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA==",
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
- "System.Memory": "4.5.5"
- }
- },
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
- "dependencies": {
- "System.Threading.Tasks.Extensions": "4.5.4"
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
},
"Microsoft.Build.Tasks.Git": {
@@ -173,20 +251,15 @@
"resolved": "8.0.0",
"contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
},
- "System.Buffers": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
- },
"System.Numerics.Vectors": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
+ "resolved": "4.6.0",
+ "contentHash": "t+SoieZsRuEyiw/J+qXUbolyO219tKQQI0+2/YI+Qv7YdGValA6WiuokrNKqjrTNsy5ABWU11bdKOzUdheteXg=="
},
"System.Runtime.CompilerServices.Unsafe": {
"type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
+ "resolved": "6.1.0",
+ "contentHash": "5o/HZxx6RVqYlhKSq8/zronDkALJZUT2Vz0hx43f0gwe8mwlM0y2nYlqdBwLMzr262Bwvpikeb/yEwkAa5PADg=="
},
"System.Threading.Tasks.Extensions": {
"type": "Transitive",
@@ -197,7 +270,7 @@
}
}
},
- ".NETStandard,Version=v2.1": {
+ "net6.0": {
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
"requested": "[8.0.0, )",
@@ -208,90 +281,17 @@
"Microsoft.SourceLink.Common": "8.0.0"
}
},
- "System.Text.Encoding.CodePages": {
- "type": "Direct",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
- "dependencies": {
- "System.Memory": "4.5.5",
- "System.Runtime.CompilerServices.Unsafe": "6.0.0"
- }
- },
- "ZstdSharp.Port": {
- "type": "Direct",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA==",
- "dependencies": {
- "System.Runtime.CompilerServices.Unsafe": "6.0.0"
- }
- },
- "Microsoft.Build.Tasks.Git": {
- "type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ=="
- },
- "Microsoft.SourceLink.Common": {
- "type": "Transitive",
- "resolved": "8.0.0",
- "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw=="
- },
"System.Buffers": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
- },
- "System.Numerics.Vectors": {
- "type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ=="
- },
- "System.Runtime.CompilerServices.Unsafe": {
- "type": "Transitive",
- "resolved": "6.0.0",
- "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg=="
- },
- "System.Memory": {
- "type": "CentralTransitive",
- "requested": "[4.5.5, )",
- "resolved": "4.5.5",
- "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
- "dependencies": {
- "System.Buffers": "4.5.1",
- "System.Numerics.Vectors": "4.4.0",
- "System.Runtime.CompilerServices.Unsafe": "4.5.3"
- }
- }
- },
- "net6.0": {
- "Microsoft.NET.ILLink.Analyzers": {
"type": "Direct",
- "requested": "[7.0.100-1.23211.1, )",
- "resolved": "7.0.100-1.23211.1",
- "contentHash": "0GvbEgDGcUQA9KuWcQU1WwYHXt1tBzNr1Nls/M57rM7NA/AndFwCaCEoJpJkmxRY7xLlPDBnmGp8h5+FNqUngg=="
- },
- "Microsoft.NET.ILLink.Tasks": {
- "type": "Direct",
- "requested": "[7.0.100-1.23211.1, )",
- "resolved": "7.0.100-1.23211.1",
- "contentHash": "tvG8XZYLjT0o3WicCyKBZysVWo1jC9HdCFmNRmddx3WbAz0UCsd0qKZqpiEo99VLA8Re+FzWK51OcRldQPbt2Q=="
- },
- "Microsoft.SourceLink.GitHub": {
- "type": "Direct",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
- "dependencies": {
- "Microsoft.Build.Tasks.Git": "8.0.0",
- "Microsoft.SourceLink.Common": "8.0.0"
- }
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
},
"ZstdSharp.Port": {
"type": "Direct",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA=="
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
@@ -307,9 +307,9 @@
"net8.0": {
"Microsoft.NET.ILLink.Tasks": {
"type": "Direct",
- "requested": "[8.0.2, )",
- "resolved": "8.0.2",
- "contentHash": "hKTrehpfVzOhAz0mreaTAZgbz0DrMEbWq4n3hAo8Ks6WdxdqQhNPvzOqn9VygKuWf1bmxPdraqzTaXriO/sn0A=="
+ "requested": "[8.0.12, )",
+ "resolved": "8.0.12",
+ "contentHash": "FV4HnQ3JI15PHnJ5PGTbz+rYvrih42oLi/7UMIshNwCwUZhTq13UzrggtXk4ygrcMcN+4jsS6hhshx2p/Zd0ig=="
},
"Microsoft.SourceLink.GitHub": {
"type": "Direct",
@@ -321,11 +321,17 @@
"Microsoft.SourceLink.Common": "8.0.0"
}
},
+ "System.Buffers": {
+ "type": "Direct",
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
+ },
"ZstdSharp.Port": {
"type": "Direct",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA=="
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g=="
},
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
diff --git a/tests/SharpCompress.Test/ArchiveTests.cs b/tests/SharpCompress.Test/ArchiveTests.cs
index 7d94b29d..94f402c9 100644
--- a/tests/SharpCompress.Test/ArchiveTests.cs
+++ b/tests/SharpCompress.Test/ArchiveTests.cs
@@ -73,27 +73,45 @@ public class ArchiveTests : ReaderTests
}
}
- protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null)
+ protected void ArchiveStreamRead(string testArchive, ReaderOptions? readerOptions = null) =>
+ ArchiveStreamRead(ArchiveFactory.AutoFactory, testArchive, readerOptions);
+
+ protected void ArchiveStreamRead(
+ IArchiveFactory archiveFactory,
+ string testArchive,
+ ReaderOptions? readerOptions = null
+ )
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
- ArchiveStreamRead(readerOptions, testArchive);
+ ArchiveStreamRead(archiveFactory, readerOptions, testArchive);
}
protected void ArchiveStreamRead(
ReaderOptions? readerOptions = null,
params string[] testArchives
+ ) => ArchiveStreamRead(ArchiveFactory.AutoFactory, readerOptions, testArchives);
+
+ protected void ArchiveStreamRead(
+ IArchiveFactory archiveFactory,
+ ReaderOptions? readerOptions = null,
+ params string[] testArchives
) =>
ArchiveStreamRead(
+ archiveFactory,
readerOptions,
testArchives.Select(x => Path.Combine(TEST_ARCHIVES_PATH, x))
);
- protected void ArchiveStreamRead(ReaderOptions? readerOptions, IEnumerable testArchives)
+ protected void ArchiveStreamRead(
+ IArchiveFactory archiveFactory,
+ ReaderOptions? readerOptions,
+ IEnumerable testArchives
+ )
{
foreach (var path in testArchives)
{
using (var stream = NonDisposingStream.Create(File.OpenRead(path), true))
- using (var archive = ArchiveFactory.Open(stream, readerOptions))
+ using (var archive = archiveFactory.Open(stream, readerOptions))
{
try
{
@@ -218,10 +236,14 @@ public class ArchiveTests : ReaderTests
}
}
- protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null)
+ protected void ArchiveFileRead(
+ IArchiveFactory archiveFactory,
+ string testArchive,
+ ReaderOptions? readerOptions = null
+ )
{
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
- using (var archive = ArchiveFactory.Open(testArchive, readerOptions))
+ using (var archive = archiveFactory.Open(new FileInfo(testArchive), readerOptions))
{
foreach (var entry in archive.Entries.Where(entry => !entry.IsDirectory))
{
@@ -234,6 +256,9 @@ public class ArchiveTests : ReaderTests
VerifyFiles();
}
+ protected void ArchiveFileRead(string testArchive, ReaderOptions? readerOptions = null) =>
+ ArchiveFileRead(ArchiveFactory.AutoFactory, testArchive, readerOptions);
+
protected void ArchiveFileSkip(
string testArchive,
string fileOrder,
@@ -270,7 +295,7 @@ public class ArchiveTests : ReaderTests
ExtractFullPath = true,
Overwrite = true,
PreserveAttributes = true,
- PreserveFileTime = true
+ PreserveFileTime = true,
}
);
}
diff --git a/tests/SharpCompress.Test/BZip2/BZip2ReaderTests.cs b/tests/SharpCompress.Test/BZip2/BZip2ReaderTests.cs
new file mode 100644
index 00000000..e0fa0583
--- /dev/null
+++ b/tests/SharpCompress.Test/BZip2/BZip2ReaderTests.cs
@@ -0,0 +1,21 @@
+using System;
+using System.IO;
+using SharpCompress.Common;
+using SharpCompress.IO;
+using SharpCompress.Readers;
+using SharpCompress.Readers.GZip;
+using Xunit;
+
+namespace SharpCompress.Test.BZip2;
+
+public class BZip2ReaderTests : ReaderTests
+{
+ [Fact]
+ public void BZip2_Reader_Factory()
+ {
+ Stream stream = new MemoryStream(
+ new byte[] { 0x42, 0x5a, 0x68, 0x34, 0x31, 0x41, 0x59, 0x26, 0x53, 0x59, 0x35 }
+ );
+ Assert.Throws(typeof(InvalidOperationException), () => ReaderFactory.Open(stream));
+ }
+}
diff --git a/tests/SharpCompress.Test/Filters/BranchExecTests.cs b/tests/SharpCompress.Test/Filters/BranchExecTests.cs
index ca9686a4..8cd3123d 100644
--- a/tests/SharpCompress.Test/Filters/BranchExecTests.cs
+++ b/tests/SharpCompress.Test/Filters/BranchExecTests.cs
@@ -91,7 +91,7 @@ public class BranchExecTests
0x00,
0x00,
0x1C,
- 0x00
+ 0x00,
];
private static byte[] X86Data { get; } =
@@ -173,7 +173,7 @@ public class BranchExecTests
0x00,
0x00,
0x1C,
- 0x00
+ 0x00,
];
private static byte[] PpcResultData { get; } =
@@ -273,7 +273,7 @@ public class BranchExecTests
0x7A,
0xB2,
0xD4,
- 0xED
+ 0xED,
];
private static byte[] PpcData { get; } =
@@ -373,7 +373,7 @@ public class BranchExecTests
0x7A,
0xB2,
0xD4,
- 0xED
+ 0xED,
];
private static byte[] ArmResultData { get; } =
@@ -473,7 +473,7 @@ public class BranchExecTests
0x00,
0xC6,
0x8F,
- 0xE2
+ 0xE2,
];
private static byte[] ArmData { get; } =
@@ -573,7 +573,7 @@ public class BranchExecTests
0x00,
0xC6,
0x8F,
- 0xE2
+ 0xE2,
];
private static byte[] ArmtResultData { get; } =
@@ -689,7 +689,7 @@ public class BranchExecTests
0x7D,
0xED,
0x11,
- 0x0F
+ 0x0F,
];
private static byte[] ArmtData { get; } =
@@ -805,7 +805,7 @@ public class BranchExecTests
0x7D,
0xED,
0x11,
- 0x0F
+ 0x0F,
];
private static byte[] Ia64ResultData { get; } =
@@ -905,7 +905,7 @@ public class BranchExecTests
0x2B,
0x72,
0xD5,
- 0x0D
+ 0x0D,
];
private static byte[] Ia64Data { get; } =
@@ -1005,7 +1005,7 @@ public class BranchExecTests
0x2B,
0x72,
0xD5,
- 0x0D
+ 0x0D,
];
private static byte[] SparcResultData { get; } =
@@ -1087,7 +1087,7 @@ public class BranchExecTests
0x91,
0x00,
0x10,
- 0x00
+ 0x00,
];
private static byte[] SparcData { get; } =
@@ -1169,7 +1169,7 @@ public class BranchExecTests
0x91,
0x00,
0x10,
- 0x00
+ 0x00,
];
private void CompareBuffer(byte[] testBuffer, byte[] targetBuffer) =>
diff --git a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs
index 56b5cd2b..6a2b9795 100644
--- a/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs
+++ b/tests/SharpCompress.Test/GZip/GZipArchiveTests.cs
@@ -106,7 +106,7 @@ public class GZipArchiveTests : ArchiveTests
}
[Fact]
- public void TestGzCrcWithMostSignificaltBitNotNegative()
+ public void TestGzCrcWithMostSignificantBitNotNegative()
{
using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
using var archive = GZipArchive.Open(stream);
@@ -116,4 +116,12 @@ public class GZipArchiveTests : ArchiveTests
Assert.InRange(entry.Crc, 0L, 0xFFFFFFFFL);
}
}
+
+ [Fact]
+ public void TestGzArchiveTypeGzip()
+ {
+ using var stream = File.OpenRead(Path.Combine(TEST_ARCHIVES_PATH, "Tar.tar.gz"));
+ using var archive = GZipArchive.Open(stream);
+ Assert.Equal(archive.Type, ArchiveType.GZip);
+ }
}
diff --git a/tests/SharpCompress.Test/Mocks/ForwardOnlyStream.cs b/tests/SharpCompress.Test/Mocks/ForwardOnlyStream.cs
index 180b8416..ae91533c 100644
--- a/tests/SharpCompress.Test/Mocks/ForwardOnlyStream.cs
+++ b/tests/SharpCompress.Test/Mocks/ForwardOnlyStream.cs
@@ -31,7 +31,7 @@ public class ForwardOnlyStream(Stream stream) : Stream
public override long Position
{
- get => throw new NotSupportedException();
+ get => stream.Position;
set => throw new NotSupportedException();
}
diff --git a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs
index 373af692..81d2c089 100644
--- a/tests/SharpCompress.Test/Rar/RarArchiveTests.cs
+++ b/tests/SharpCompress.Test/Rar/RarArchiveTests.cs
@@ -235,7 +235,7 @@ public class RarArchiveTests : ArchiveTests
"Rar.multi.part03.rar",
"Rar.multi.part04.rar",
"Rar.multi.part05.rar",
- "Rar.multi.part06.rar"
+ "Rar.multi.part06.rar",
],
false
);
@@ -249,7 +249,7 @@ public class RarArchiveTests : ArchiveTests
"Rar5.multi.part03.rar",
"Rar5.multi.part04.rar",
"Rar5.multi.part05.rar",
- "Rar5.multi.part06.rar"
+ "Rar5.multi.part06.rar",
],
false
);
@@ -278,7 +278,7 @@ public class RarArchiveTests : ArchiveTests
"Rar.multi.solid.part03.rar",
"Rar.multi.solid.part04.rar",
"Rar.multi.solid.part05.rar",
- "Rar.multi.solid.part06.rar"
+ "Rar.multi.solid.part06.rar",
],
true
);
@@ -348,7 +348,7 @@ public class RarArchiveTests : ArchiveTests
"Rar2.multi.r02",
"Rar2.multi.r03",
"Rar2.multi.r04",
- "Rar2.multi.r05"
+ "Rar2.multi.r05",
],
false
);
@@ -424,7 +424,7 @@ public class RarArchiveTests : ArchiveTests
"Rar4.split.003",
"Rar4.split.004",
"Rar4.split.005",
- "Rar4.split.006"
+ "Rar4.split.006",
}
);
@@ -440,7 +440,7 @@ public class RarArchiveTests : ArchiveTests
"Rar2.multi.r02",
"Rar2.multi.r03",
"Rar2.multi.r04",
- "Rar2.multi.r05"
+ "Rar2.multi.r05",
}
);
@@ -456,7 +456,7 @@ public class RarArchiveTests : ArchiveTests
"Rar4.multi.part04.rar",
"Rar4.multi.part05.rar",
"Rar4.multi.part06.rar",
- "Rar4.multi.part07.rar"
+ "Rar4.multi.part07.rar",
}
);
@@ -470,7 +470,7 @@ public class RarArchiveTests : ArchiveTests
"Rar4.multi.part04.rar",
"Rar4.multi.part05.rar",
"Rar4.multi.part06.rar",
- "Rar4.multi.part07.rar"
+ "Rar4.multi.part07.rar",
],
false
);
@@ -486,7 +486,7 @@ public class RarArchiveTests : ArchiveTests
"Rar4.split.003",
"Rar4.split.004",
"Rar4.split.005",
- "Rar4.split.006"
+ "Rar4.split.006",
]
);
@@ -515,7 +515,7 @@ public class RarArchiveTests : ArchiveTests
ArchiveStreamMultiRead(
null,
[
- "Rar4.split.001"
+ "Rar4.split.001",
//"Rar4.split.002",
//"Rar4.split.003",
//"Rar4.split.004",
@@ -557,7 +557,7 @@ public class RarArchiveTests : ArchiveTests
[
[0, 1], //exe - Rar4.multi.part01.rar to Rar4.multi.part02.rar
[1, 5], //jpg - Rar4.multi.part02.rar to Rar4.multi.part06.rar
- [5, 6] //txt - Rar4.multi.part06.rar to Rar4.multi.part07.rar
+ [5, 6], //txt - Rar4.multi.part06.rar to Rar4.multi.part07.rar
],
null,
"Rar4.multi.part01.rar",
diff --git a/tests/SharpCompress.Test/Rar/RarReaderTests.cs b/tests/SharpCompress.Test/Rar/RarReaderTests.cs
index 6ba605a5..5d3c0e64 100644
--- a/tests/SharpCompress.Test/Rar/RarReaderTests.cs
+++ b/tests/SharpCompress.Test/Rar/RarReaderTests.cs
@@ -19,7 +19,7 @@ public class RarReaderTests : ReaderTests
"Rar.multi.part03.rar",
"Rar.multi.part04.rar",
"Rar.multi.part05.rar",
- "Rar.multi.part06.rar"
+ "Rar.multi.part06.rar",
]
);
@@ -32,7 +32,7 @@ public class RarReaderTests : ReaderTests
"Rar5.multi.part03.rar",
"Rar5.multi.part04.rar",
"Rar5.multi.part05.rar",
- "Rar5.multi.part06.rar"
+ "Rar5.multi.part06.rar",
]
);
@@ -66,7 +66,7 @@ public class RarReaderTests : ReaderTests
"Rar.EncryptedParts.part03.rar",
"Rar.EncryptedParts.part04.rar",
"Rar.EncryptedParts.part05.rar",
- "Rar.EncryptedParts.part06.rar"
+ "Rar.EncryptedParts.part06.rar",
]
);
@@ -102,7 +102,7 @@ public class RarReaderTests : ReaderTests
"Rar.multi.part03.rar",
"Rar.multi.part04.rar",
"Rar.multi.part05.rar",
- "Rar.multi.part06.rar"
+ "Rar.multi.part06.rar",
]
);
@@ -115,7 +115,7 @@ public class RarReaderTests : ReaderTests
"Rar5.multi.part03.rar",
"Rar5.multi.part04.rar",
"Rar5.multi.part05.rar",
- "Rar5.multi.part06.rar"
+ "Rar5.multi.part06.rar",
]
);
@@ -338,7 +338,7 @@ public class RarReaderTests : ReaderTests
"Rar.EncryptedParts.part03.rar",
"Rar.EncryptedParts.part04.rar",
"Rar.EncryptedParts.part05.rar",
- "Rar.EncryptedParts.part06.rar"
+ "Rar.EncryptedParts.part06.rar",
};
using var reader = RarReader.Open(
diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs
index 32d978a2..544741ef 100644
--- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs
+++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveTests.cs
@@ -4,6 +4,7 @@ using System.Linq;
using SharpCompress.Archives;
using SharpCompress.Archives.SevenZip;
using SharpCompress.Common;
+using SharpCompress.Factories;
using SharpCompress.Readers;
using Xunit;
@@ -54,6 +55,14 @@ public class SevenZipArchiveTests : ArchiveTests
[Fact]
public void SevenZipArchive_LZMA2_PathRead() => ArchiveFileRead("7Zip.LZMA2.7z");
+ [Fact]
+ public void SevenZipArchive_LZMA2_EXE_StreamRead() =>
+ ArchiveStreamRead(new SevenZipFactory(), "7Zip.LZMA2.exe", new() { LookForHeader = true });
+
+ [Fact]
+ public void SevenZipArchive_LZMA2_EXE_PathRead() =>
+ ArchiveFileRead(new SevenZipFactory(), "7Zip.LZMA2.exe", new() { LookForHeader = true });
+
[Fact]
public void SevenZipArchive_LZMA2AES_StreamRead() =>
ArchiveStreamRead("7Zip.LZMA2.Aes.7z", new ReaderOptions { Password = "testpassword" });
diff --git a/tests/SharpCompress.Test/SharpCompress.Test.csproj b/tests/SharpCompress.Test/SharpCompress.Test.csproj
index 3bfeaa3e..22f99b20 100644
--- a/tests/SharpCompress.Test/SharpCompress.Test.csproj
+++ b/tests/SharpCompress.Test/SharpCompress.Test.csproj
@@ -1,8 +1,10 @@
- net8.0;net462
+ net8.0;net48
SharpCompress.Test
SharpCompress.Test
+ SharpCompress.Test.snk
+ true
diff --git a/tests/SharpCompress.Test/SharpCompress.Test.snk b/tests/SharpCompress.Test/SharpCompress.Test.snk
new file mode 100644
index 00000000..5a9ce097
Binary files /dev/null and b/tests/SharpCompress.Test/SharpCompress.Test.snk differ
diff --git a/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs b/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs
index 2eea6607..634929b1 100644
--- a/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs
+++ b/tests/SharpCompress.Test/Streams/LzmaStreamTests.cs
@@ -174,7 +174,7 @@ public class LzmaStreamTests
0xF1,
0x76,
0x03,
- 0x90
+ 0x90,
];
///
@@ -509,7 +509,7 @@ public class LzmaStreamTests
0x0A,
0x00,
0x00,
- 0x00
+ 0x00,
];
[Fact]
diff --git a/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs b/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs
index 56f934d6..ab8e6656 100644
--- a/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs
+++ b/tests/SharpCompress.Test/Streams/ZlibBaseStreamTests.cs
@@ -34,7 +34,7 @@ public class ZLibBaseStreamTests
0x8b,
0xce,
0x49,
- 0xd2
+ 0xd2,
};
var buf = new byte[plainData.Length * 2];
diff --git a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
index bbf96c00..efbde472 100644
--- a/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
+++ b/tests/SharpCompress.Test/Tar/TarArchiveTests.cs
@@ -252,7 +252,7 @@ public class TarArchiveTests : ArchiveTests
[Fact]
public void Tar_Read_One_At_A_Time()
{
- var archiveEncoding = new ArchiveEncoding { Default = Encoding.UTF8, };
+ var archiveEncoding = new ArchiveEncoding { Default = Encoding.UTF8 };
var tarWriterOptions = new TarWriterOptions(CompressionType.None, true)
{
ArchiveEncoding = archiveEncoding,
@@ -287,4 +287,12 @@ public class TarArchiveTests : ArchiveTests
Assert.Equal(2, numberOfEntries);
}
+
+ [Fact]
+ public void Tar_Detect_Test()
+ {
+ var isTar = TarArchive.IsTarFile(Path.Combine(TEST_ARCHIVES_PATH, "false.positive.tar"));
+
+ Assert.False(isTar);
+ }
}
diff --git a/tests/SharpCompress.Test/Tar/TarReaderTests.cs b/tests/SharpCompress.Test/Tar/TarReaderTests.cs
index bb10db98..d2b01ef0 100644
--- a/tests/SharpCompress.Test/Tar/TarReaderTests.cs
+++ b/tests/SharpCompress.Test/Tar/TarReaderTests.cs
@@ -183,6 +183,21 @@ public class TarReaderTests : ReaderTests
Assert.Throws(() => reader.MoveToNextEntry());
}
+ [Fact]
+ public void Tar_Corrupted()
+ {
+ var archiveFullPath = Path.Combine(TEST_ARCHIVES_PATH, "TarCorrupted.tar");
+ using Stream stream = File.OpenRead(archiveFullPath);
+ using var reader = ReaderFactory.Open(stream);
+ var memoryStream = new MemoryStream();
+
+ Assert.True(reader.MoveToNextEntry());
+ Assert.True(reader.MoveToNextEntry());
+ reader.WriteEntryTo(memoryStream);
+ stream.Close();
+ Assert.Throws(() => reader.MoveToNextEntry());
+ }
+
#if !NETFRAMEWORK
[Fact]
public void Tar_GZip_With_Symlink_Entries()
@@ -217,7 +232,7 @@ public class TarReaderTests : ReaderTests
}
link.CreateSymbolicLinkTo(targetPath);
}
- }
+ },
}
);
if (!isWindows)
diff --git a/tests/SharpCompress.Test/TestBase.cs b/tests/SharpCompress.Test/TestBase.cs
index 184e6442..f9cfb8a3 100644
--- a/tests/SharpCompress.Test/TestBase.cs
+++ b/tests/SharpCompress.Test/TestBase.cs
@@ -1,3 +1,4 @@
+global using SharpCompress.Helpers;
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/tests/SharpCompress.Test/WriterTests.cs b/tests/SharpCompress.Test/WriterTests.cs
index 50695ef1..ba08b3d2 100644
--- a/tests/SharpCompress.Test/WriterTests.cs
+++ b/tests/SharpCompress.Test/WriterTests.cs
@@ -22,7 +22,7 @@ public class WriterTests : TestBase
{
using (Stream stream = File.OpenWrite(Path.Combine(SCRATCH2_FILES_PATH, archive)))
{
- var writerOptions = new WriterOptions(compressionType) { LeaveStreamOpen = true, };
+ var writerOptions = new WriterOptions(compressionType) { LeaveStreamOpen = true };
writerOptions.ArchiveEncoding.Default = encoding ?? Encoding.Default;
diff --git a/tests/SharpCompress.Test/Xz/XZBlockTests.cs b/tests/SharpCompress.Test/Xz/XZBlockTests.cs
index 0d6c7d9a..44245075 100644
--- a/tests/SharpCompress.Test/Xz/XZBlockTests.cs
+++ b/tests/SharpCompress.Test/Xz/XZBlockTests.cs
@@ -94,4 +94,19 @@ public class XzBlockTests : XzTestsBase
sr.ReadToEnd();
Assert.Equal(0L, CompressedIndexedStream.Position % 4L);
}
+
+ [Fact]
+ public void HandlesPaddingInUnalignedBlock()
+ {
+ var compressedUnaligned = new byte[Compressed.Length + 1];
+ Compressed.CopyTo(compressedUnaligned, 1);
+ var compressedUnalignedStream = new MemoryStream(compressedUnaligned);
+ compressedUnalignedStream.Position = 13;
+
+ // Compressed's only block has no padding.
+ var xzBlock = new XZBlock(compressedUnalignedStream, CheckType.CRC64, 8);
+ var sr = new StreamReader(xzBlock);
+ sr.ReadToEnd();
+ Assert.Equal(1L, compressedUnalignedStream.Position % 4L);
+ }
}
diff --git a/tests/SharpCompress.Test/Xz/XZTestsBase.cs b/tests/SharpCompress.Test/Xz/XZTestsBase.cs
index a679934e..d1c15638 100644
--- a/tests/SharpCompress.Test/Xz/XZTestsBase.cs
+++ b/tests/SharpCompress.Test/Xz/XZTestsBase.cs
@@ -61,7 +61,7 @@ public abstract class XzTestsBase : IDisposable
0x00,
0x01,
0x59,
- 0x5a
+ 0x5a,
];
protected static byte[] OriginalEmptyBytes => Encoding.ASCII.GetBytes(OriginalEmpty);
@@ -451,7 +451,7 @@ public abstract class XzTestsBase : IDisposable
0x00,
0x04,
0x59,
- 0x5a
+ 0x5a,
];
protected static byte[] OriginalBytes => Encoding.ASCII.GetBytes(Original);
@@ -1119,7 +1119,7 @@ public abstract class XzTestsBase : IDisposable
0x00,
0x01,
0x59,
- 0x5a
+ 0x5a,
];
protected static byte[] OriginalIndexedBytes => Encoding.ASCII.GetBytes(OriginalIndexed);
diff --git a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
index 494e02c9..8419f58f 100644
--- a/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
+++ b/tests/SharpCompress.Test/Zip/ZipArchiveTests.cs
@@ -16,14 +16,6 @@ public class ZipArchiveTests : ArchiveTests
{
public ZipArchiveTests() => UseExtensionInsteadOfNameToVerify = true;
- [Fact]
- public void Zip_Shrink_ArchiveStreamRead()
- {
- UseExtensionInsteadOfNameToVerify = true;
- UseCaseInsensitiveToVerify = true;
- ArchiveStreamRead("Zip.shrink.zip");
- }
-
[Fact]
public void Zip_ZipX_ArchiveStreamRead() => ArchiveStreamRead("Zip.zipx");
@@ -129,7 +121,7 @@ public class ZipArchiveTests : ArchiveTests
"Zip.deflate.split.003",
"Zip.deflate.split.004",
"Zip.deflate.split.005",
- "Zip.deflate.split.006"
+ "Zip.deflate.split.006",
}
);
@@ -183,6 +175,54 @@ public class ZipArchiveTests : ArchiveTests
[Fact]
public void Zip_Zip64_ArchiveFileRead() => ArchiveFileRead("Zip.zip64.zip");
+ [Fact]
+ public void Zip_Shrink_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.shrink.zip");
+ }
+
+ [Fact]
+ public void Zip_Implode_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.implode.zip");
+ }
+
+ [Fact]
+ public void Zip_Reduce1_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.reduce1.zip");
+ }
+
+ [Fact]
+ public void Zip_Reduce2_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.reduce2.zip");
+ }
+
+ [Fact]
+ public void Zip_Reduce3_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.reduce3.zip");
+ }
+
+ [Fact]
+ public void Zip_Reduce4_ArchiveStreamRead()
+ {
+ UseExtensionInsteadOfNameToVerify = true;
+ UseCaseInsensitiveToVerify = true;
+ ArchiveStreamRead("Zip.reduce4.zip");
+ }
+
[Fact]
public void Zip_Random_Write_Remove()
{
@@ -715,7 +755,7 @@ public class ZipArchiveTests : ArchiveTests
"Folder/File2.rtf",
"Folder2/File1.txt",
"Folder2/File2.txt",
- "DEADBEEF"
+ "DEADBEEF",
};
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip");
using var stream = File.Open(zipPath, FileMode.Open, FileAccess.Read);
@@ -744,7 +784,7 @@ public class ZipArchiveTests : ArchiveTests
ArchiveEncoding = new ArchiveEncoding
{
Default = Encoding.GetEncoding("shift_jis"),
- }
+ },
}
);
var reader = archive.ExtractAllEntries();
@@ -760,7 +800,7 @@ public class ZipArchiveTests : ArchiveTests
ArchiveEncoding = new ArchiveEncoding
{
Forced = Encoding.GetEncoding("shift_jis"),
- }
+ },
}
);
var reader = archive.ExtractAllEntries();
@@ -768,4 +808,16 @@ public class ZipArchiveTests : ArchiveTests
Assert.Equal("きょきゅんきゃんきゅ_wav.frq", reader.Entry.Key);
}
}
+
+ [Fact]
+ public void TestDataDescriptorRead()
+ {
+ using var archive = ArchiveFactory.Open(
+ Path.Combine(TEST_ARCHIVES_PATH, "Zip.none.datadescriptors.zip")
+ );
+ var firstEntry = archive.Entries.First();
+ Assert.Equal(199, firstEntry.Size);
+ using var _ = firstEntry.OpenEntryStream();
+ Assert.Equal(199, firstEntry.Size);
+ }
}
diff --git a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
index 3296bcb0..69c6326f 100644
--- a/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
+++ b/tests/SharpCompress.Test/Zip/ZipReaderTests.cs
@@ -248,7 +248,7 @@ public class ZipReaderTests : ReaderTests
var expected = new[]
{
new Tuple("foo.txt", Array.Empty()),
- new Tuple("foo2.txt", new byte[10])
+ new Tuple("foo2.txt", new byte[10]),
};
using var memory = new MemoryStream();
diff --git a/tests/SharpCompress.Test/packages.lock.json b/tests/SharpCompress.Test/packages.lock.json
index a7d04fce..babef83e 100644
--- a/tests/SharpCompress.Test/packages.lock.json
+++ b/tests/SharpCompress.Test/packages.lock.json
@@ -1,72 +1,65 @@
{
"version": 2,
"dependencies": {
- ".NETFramework,Version=v4.6.2": {
+ ".NETFramework,Version=v4.8": {
"FluentAssertions": {
"type": "Direct",
- "requested": "[6.12.0, )",
- "resolved": "6.12.0",
- "contentHash": "ZXhHT2YwP9lajrwSKbLlFqsmCCvFJMoRSK9t7sImfnCyd0OB3MhgxdoMcVqxbq1iyxD6mD2fiackWmBb7ayiXQ==",
+ "requested": "[7.0.0, )",
+ "resolved": "7.0.0",
+ "contentHash": "mTLbcU991EQ1SEmNbVBaGGGJy0YFzvGd1sYJGNZ07nlPKuyHSn1I22aeKzqQXgEiaKyRO6MSCto9eN9VxMwBdA==",
"dependencies": {
- "System.Threading.Tasks.Extensions": "4.5.0"
+ "System.Threading.Tasks.Extensions": "4.5.4"
}
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
- "requested": "[17.9.0, )",
- "resolved": "17.9.0",
- "contentHash": "7GUNAUbJYn644jzwLm5BD3a2p9C1dmP8Hr6fDPDxgItQk9hBs1Svdxzz07KQ/UphMSmgza9AbijBJGmw5D658A==",
+ "requested": "[17.12.0, )",
+ "resolved": "17.12.0",
+ "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==",
"dependencies": {
- "Microsoft.CodeCoverage": "17.9.0"
+ "Microsoft.CodeCoverage": "17.12.0"
}
},
- "Microsoft.NETFramework.ReferenceAssemblies": {
+ "Microsoft.SourceLink.GitHub": {
"type": "Direct",
- "requested": "[1.0.3, )",
- "resolved": "1.0.3",
- "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
"dependencies": {
- "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3"
+ "Microsoft.Build.Tasks.Git": "8.0.0",
+ "Microsoft.SourceLink.Common": "8.0.0"
}
},
"xunit": {
"type": "Direct",
- "requested": "[2.7.1, )",
- "resolved": "2.7.1",
- "contentHash": "9o050yCLzPvHxbrAkaHnI1j+YfPvRw+/ncvKbTfzIhO4JvQA0rPgoICJxXHMkscfgXmLFwZ8107ehnMUVzE23A==",
+ "requested": "[2.9.3, )",
+ "resolved": "2.9.3",
+ "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==",
"dependencies": {
- "xunit.analyzers": "1.12.0",
- "xunit.assert": "2.7.1",
- "xunit.core": "[2.7.1]"
+ "xunit.analyzers": "1.18.0",
+ "xunit.assert": "2.9.3",
+ "xunit.core": "[2.9.3]"
}
},
"xunit.runner.visualstudio": {
"type": "Direct",
- "requested": "[2.5.8, )",
- "resolved": "2.5.8",
- "contentHash": "ZJTm71neOfZcUnqdyY0A0Qgcg1162DoOq6+VpCCsOaD9rwCK5alcjOEHeu17sEekzq4qNv3kyelx6lUMsAt/eA==",
+ "requested": "[3.0.1, )",
+ "resolved": "3.0.1",
+ "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg==",
"dependencies": {
- "Microsoft.TestPlatform.ObjectModel": "17.9.0"
+ "Microsoft.TestPlatform.ObjectModel": "17.12.0"
}
},
"Xunit.SkippableFact": {
"type": "Direct",
- "requested": "[1.4.13, )",
- "resolved": "1.4.13",
- "contentHash": "IyzZNvJEtXGlXrzxDiSbtH5Lyxf4iJdRQADuyjGdDf00LjXRLJwIoezQNFhFGKTMtvk8IIgaSHxW4mAV4O7b8A==",
+ "requested": "[1.5.23, )",
+ "resolved": "1.5.23",
+ "contentHash": "JlKobLTlsGcuJ8OtoodxL63bUagHSVBnF+oQ2GgnkwNqK+XYjeYyhQasULi5Ebx1MNDGNbOMplQYr89mR+nItQ==",
"dependencies": {
- "Validation": "2.4.18",
+ "Validation": "2.5.51",
"xunit.extensibility.execution": "2.4.0"
}
},
- "Microsoft.Bcl.AsyncInterfaces": {
- "type": "Transitive",
- "resolved": "5.0.0",
- "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
- "dependencies": {
- "System.Threading.Tasks.Extensions": "4.5.4"
- }
- },
"Microsoft.Build.Tasks.Git": {
"type": "Transitive",
"resolved": "8.0.0",
@@ -74,13 +67,8 @@
},
"Microsoft.CodeCoverage": {
"type": "Transitive",
- "resolved": "17.9.0",
- "contentHash": "RGD37ZSrratfScYXm7M0HjvxMxZyWZL4jm+XgMZbkIY1UPgjUpbNA/t+WTGj/rC/0Hm9A3IrH3ywbKZkOCnoZA=="
- },
- "Microsoft.NETFramework.ReferenceAssemblies.net462": {
- "type": "Transitive",
- "resolved": "1.0.3",
- "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ=="
+ "resolved": "17.12.0",
+ "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
@@ -89,17 +77,12 @@
},
"Microsoft.TestPlatform.ObjectModel": {
"type": "Transitive",
- "resolved": "17.9.0",
- "contentHash": "1ilw/8vgmjLyKU+2SKXKXaOqpYFJCQfGqGz+x0cosl981VzjrY74Sv6qAJv+neZMZ9ZMxF3ArN6kotaQ4uvEBw==",
+ "resolved": "17.12.0",
+ "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==",
"dependencies": {
"System.Reflection.Metadata": "1.6.0"
}
},
- "System.Buffers": {
- "type": "Transitive",
- "resolved": "4.5.1",
- "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg=="
- },
"System.Collections.Immutable": {
"type": "Transitive",
"resolved": "1.5.0",
@@ -133,8 +116,8 @@
},
"Validation": {
"type": "Transitive",
- "resolved": "2.4.18",
- "contentHash": "NfvWJ1QeuZ1FQCkqgXTu1cOkRkbNCfxs4Tat+abXLwom6OXbULVhRGp34BTvVB4XPxj6VIAl7KfLfStXMt/Ehw=="
+ "resolved": "2.5.51",
+ "contentHash": "g/Aug7PVWaenlJ0QUyt/mEetngkQNsMCuNeRVXbcJED1nZS7JcK+GTU4kz3jcQ7bFuKfi8PF4ExXH7XSFNuSLQ=="
},
"xunit.abstractions": {
"type": "Transitive",
@@ -143,61 +126,64 @@
},
"xunit.analyzers": {
"type": "Transitive",
- "resolved": "1.12.0",
- "contentHash": "w23LH3aXade2WXKvXi0oA/uV15fpgUMjsPq1x91iQckzgWApgAiijNHmfFQtqNPm41wfrdbRl7nSJRd0yux/dw=="
+ "resolved": "1.18.0",
+ "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ=="
},
"xunit.assert": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "JqvXS4yX+PtJn5BuqoKkYav7I0g4nXcxRbGTomDwVQjFccOdyfYKpuPOHX/DqrPCcL+MIHrGVdP3bveUXlvdnA=="
+ "resolved": "2.9.3",
+ "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA=="
},
"xunit.core": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "hcODgS+RXdjmXq0zQzmRbERQgY+bAGGx1bdH3370t/8CTGmIEU2qAc1dQAjIRpARsacR0cj6LLJDUF5BNQNKTQ==",
+ "resolved": "2.9.3",
+ "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==",
"dependencies": {
- "xunit.extensibility.core": "[2.7.1]",
- "xunit.extensibility.execution": "[2.7.1]"
+ "xunit.extensibility.core": "[2.9.3]",
+ "xunit.extensibility.execution": "[2.9.3]"
}
},
"xunit.extensibility.core": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "yLX4XlBFkvNYCzf+DEzlNk45KsSlu9W93IJHBmtUP96qZ9XyRYDFlwMj6BCcOhDKVNrZxSM8bqu4F/Qud4ehxA==",
+ "resolved": "2.9.3",
+ "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==",
"dependencies": {
"xunit.abstractions": "2.0.3"
}
},
"xunit.extensibility.execution": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "ei3dKF8agj4UKkJ6KkaZ5/Gcif3if6hBsyzegIQJonZDSKZFvb0AyKtyOhDfggBaXVL5iXZExITdRkfjC95yhw==",
+ "resolved": "2.9.3",
+ "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==",
"dependencies": {
- "xunit.extensibility.core": "[2.7.1]"
+ "xunit.extensibility.core": "[2.9.3]"
}
},
"sharpcompress": {
"type": "Project",
"dependencies": {
- "Microsoft.SourceLink.GitHub": "[8.0.0, )",
- "System.Memory": "[4.5.5, )",
- "System.Text.Encoding.CodePages": "[8.0.0, )",
- "ZstdSharp.Port": "[0.7.6, )"
+ "System.Buffers": "[4.6.0, )",
+ "ZstdSharp.Port": "[0.8.4, )"
}
},
- "Microsoft.SourceLink.GitHub": {
+ "Microsoft.Bcl.AsyncInterfaces": {
"type": "CentralTransitive",
"requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
+ "resolved": "5.0.0",
+ "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==",
"dependencies": {
- "Microsoft.Build.Tasks.Git": "8.0.0",
- "Microsoft.SourceLink.Common": "8.0.0"
+ "System.Threading.Tasks.Extensions": "4.5.4"
}
},
+ "System.Buffers": {
+ "type": "CentralTransitive",
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
+ },
"System.Memory": {
"type": "CentralTransitive",
- "requested": "[4.5.5, )",
+ "requested": "[4.6.0, )",
"resolved": "4.5.5",
"contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==",
"dependencies": {
@@ -206,45 +192,46 @@
"System.Runtime.CompilerServices.Unsafe": "4.5.3"
}
},
- "System.Text.Encoding.CodePages": {
- "type": "CentralTransitive",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "OZIsVplFGaVY90G2SbpgU7EnCoOO5pw1t4ic21dBF3/1omrJFpAGoNAVpPyMVOC90/hvgkGG3VFqR13YgZMQfg==",
- "dependencies": {
- "System.Memory": "4.5.5",
- "System.Runtime.CompilerServices.Unsafe": "6.0.0"
- }
- },
"ZstdSharp.Port": {
"type": "CentralTransitive",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA==",
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g==",
"dependencies": {
"Microsoft.Bcl.AsyncInterfaces": "5.0.0",
- "System.Memory": "4.5.5"
+ "System.Memory": "4.5.5",
+ "System.Runtime.CompilerServices.Unsafe": "6.0.0"
}
}
},
"net8.0": {
"FluentAssertions": {
"type": "Direct",
- "requested": "[6.12.0, )",
- "resolved": "6.12.0",
- "contentHash": "ZXhHT2YwP9lajrwSKbLlFqsmCCvFJMoRSK9t7sImfnCyd0OB3MhgxdoMcVqxbq1iyxD6mD2fiackWmBb7ayiXQ==",
+ "requested": "[7.0.0, )",
+ "resolved": "7.0.0",
+ "contentHash": "mTLbcU991EQ1SEmNbVBaGGGJy0YFzvGd1sYJGNZ07nlPKuyHSn1I22aeKzqQXgEiaKyRO6MSCto9eN9VxMwBdA==",
"dependencies": {
- "System.Configuration.ConfigurationManager": "4.4.0"
+ "System.Configuration.ConfigurationManager": "6.0.0"
}
},
"Microsoft.NET.Test.Sdk": {
"type": "Direct",
- "requested": "[17.9.0, )",
- "resolved": "17.9.0",
- "contentHash": "7GUNAUbJYn644jzwLm5BD3a2p9C1dmP8Hr6fDPDxgItQk9hBs1Svdxzz07KQ/UphMSmgza9AbijBJGmw5D658A==",
+ "requested": "[17.12.0, )",
+ "resolved": "17.12.0",
+ "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==",
"dependencies": {
- "Microsoft.CodeCoverage": "17.9.0",
- "Microsoft.TestPlatform.TestHost": "17.9.0"
+ "Microsoft.CodeCoverage": "17.12.0",
+ "Microsoft.TestPlatform.TestHost": "17.12.0"
+ }
+ },
+ "Microsoft.SourceLink.GitHub": {
+ "type": "Direct",
+ "requested": "[8.0.0, )",
+ "resolved": "8.0.0",
+ "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
+ "dependencies": {
+ "Microsoft.Build.Tasks.Git": "8.0.0",
+ "Microsoft.SourceLink.Common": "8.0.0"
}
},
"Mono.Posix.NETStandard": {
@@ -255,28 +242,28 @@
},
"xunit": {
"type": "Direct",
- "requested": "[2.7.1, )",
- "resolved": "2.7.1",
- "contentHash": "9o050yCLzPvHxbrAkaHnI1j+YfPvRw+/ncvKbTfzIhO4JvQA0rPgoICJxXHMkscfgXmLFwZ8107ehnMUVzE23A==",
+ "requested": "[2.9.3, )",
+ "resolved": "2.9.3",
+ "contentHash": "TlXQBinK35LpOPKHAqbLY4xlEen9TBafjs0V5KnA4wZsoQLQJiirCR4CbIXvOH8NzkW4YeJKP5P/Bnrodm0h9Q==",
"dependencies": {
- "xunit.analyzers": "1.12.0",
- "xunit.assert": "2.7.1",
- "xunit.core": "[2.7.1]"
+ "xunit.analyzers": "1.18.0",
+ "xunit.assert": "2.9.3",
+ "xunit.core": "[2.9.3]"
}
},
"xunit.runner.visualstudio": {
"type": "Direct",
- "requested": "[2.5.8, )",
- "resolved": "2.5.8",
- "contentHash": "ZJTm71neOfZcUnqdyY0A0Qgcg1162DoOq6+VpCCsOaD9rwCK5alcjOEHeu17sEekzq4qNv3kyelx6lUMsAt/eA=="
+ "requested": "[3.0.1, )",
+ "resolved": "3.0.1",
+ "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg=="
},
"Xunit.SkippableFact": {
"type": "Direct",
- "requested": "[1.4.13, )",
- "resolved": "1.4.13",
- "contentHash": "IyzZNvJEtXGlXrzxDiSbtH5Lyxf4iJdRQADuyjGdDf00LjXRLJwIoezQNFhFGKTMtvk8IIgaSHxW4mAV4O7b8A==",
+ "requested": "[1.5.23, )",
+ "resolved": "1.5.23",
+ "contentHash": "JlKobLTlsGcuJ8OtoodxL63bUagHSVBnF+oQ2GgnkwNqK+XYjeYyhQasULi5Ebx1MNDGNbOMplQYr89mR+nItQ==",
"dependencies": {
- "Validation": "2.4.18",
+ "Validation": "2.5.51",
"xunit.extensibility.execution": "2.4.0"
}
},
@@ -287,8 +274,8 @@
},
"Microsoft.CodeCoverage": {
"type": "Transitive",
- "resolved": "17.9.0",
- "contentHash": "RGD37ZSrratfScYXm7M0HjvxMxZyWZL4jm+XgMZbkIY1UPgjUpbNA/t+WTGj/rC/0Hm9A3IrH3ywbKZkOCnoZA=="
+ "resolved": "17.12.0",
+ "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA=="
},
"Microsoft.SourceLink.Common": {
"type": "Transitive",
@@ -297,21 +284,26 @@
},
"Microsoft.TestPlatform.ObjectModel": {
"type": "Transitive",
- "resolved": "17.9.0",
- "contentHash": "1ilw/8vgmjLyKU+2SKXKXaOqpYFJCQfGqGz+x0cosl981VzjrY74Sv6qAJv+neZMZ9ZMxF3ArN6kotaQ4uvEBw==",
+ "resolved": "17.12.0",
+ "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==",
"dependencies": {
"System.Reflection.Metadata": "1.6.0"
}
},
"Microsoft.TestPlatform.TestHost": {
"type": "Transitive",
- "resolved": "17.9.0",
- "contentHash": "Spmg7Wx49Ya3SxBjyeAR+nQpjMTKZwTwpZ7KyeOTIqI/WHNPnBU4HUvl5kuHPQAwGWqMy4FGZja1HvEwvoaDiA==",
+ "resolved": "17.12.0",
+ "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==",
"dependencies": {
- "Microsoft.TestPlatform.ObjectModel": "17.9.0",
+ "Microsoft.TestPlatform.ObjectModel": "17.12.0",
"Newtonsoft.Json": "13.0.1"
}
},
+ "Microsoft.Win32.SystemEvents": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A=="
+ },
"Newtonsoft.Json": {
"type": "Transitive",
"resolved": "13.0.1",
@@ -319,10 +311,19 @@
},
"System.Configuration.ConfigurationManager": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "gWwQv/Ug1qWJmHCmN17nAbxJYmQBM/E94QxKLksvUiiKB1Ld3Sc/eK1lgmbSjDFxkQhVuayI/cGFZhpBSodLrg==",
+ "resolved": "6.0.0",
+ "contentHash": "7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
"dependencies": {
- "System.Security.Cryptography.ProtectedData": "4.4.0"
+ "System.Security.Cryptography.ProtectedData": "6.0.0",
+ "System.Security.Permissions": "6.0.0"
+ }
+ },
+ "System.Drawing.Common": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
+ "dependencies": {
+ "Microsoft.Win32.SystemEvents": "6.0.0"
}
},
"System.Reflection.Metadata": {
@@ -330,15 +331,37 @@
"resolved": "1.6.0",
"contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ=="
},
+ "System.Security.AccessControl": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ=="
+ },
"System.Security.Cryptography.ProtectedData": {
"type": "Transitive",
- "resolved": "4.4.0",
- "contentHash": "cJV7ScGW7EhatRsjehfvvYVBvtiSMKgN8bOVI0bQhnF5bU7vnHVIsH49Kva7i7GWaWYvmEzkYVk1TC+gZYBEog=="
+ "resolved": "6.0.0",
+ "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ=="
+ },
+ "System.Security.Permissions": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
+ "dependencies": {
+ "System.Security.AccessControl": "6.0.0",
+ "System.Windows.Extensions": "6.0.0"
+ }
+ },
+ "System.Windows.Extensions": {
+ "type": "Transitive",
+ "resolved": "6.0.0",
+ "contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
+ "dependencies": {
+ "System.Drawing.Common": "6.0.0"
+ }
},
"Validation": {
"type": "Transitive",
- "resolved": "2.4.18",
- "contentHash": "NfvWJ1QeuZ1FQCkqgXTu1cOkRkbNCfxs4Tat+abXLwom6OXbULVhRGp34BTvVB4XPxj6VIAl7KfLfStXMt/Ehw=="
+ "resolved": "2.5.51",
+ "contentHash": "g/Aug7PVWaenlJ0QUyt/mEetngkQNsMCuNeRVXbcJED1nZS7JcK+GTU4kz3jcQ7bFuKfi8PF4ExXH7XSFNuSLQ=="
},
"xunit.abstractions": {
"type": "Transitive",
@@ -347,61 +370,57 @@
},
"xunit.analyzers": {
"type": "Transitive",
- "resolved": "1.12.0",
- "contentHash": "w23LH3aXade2WXKvXi0oA/uV15fpgUMjsPq1x91iQckzgWApgAiijNHmfFQtqNPm41wfrdbRl7nSJRd0yux/dw=="
+ "resolved": "1.18.0",
+ "contentHash": "OtFMHN8yqIcYP9wcVIgJrq01AfTxijjAqVDy/WeQVSyrDC1RzBWeQPztL49DN2syXRah8TYnfvk035s7L95EZQ=="
},
"xunit.assert": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "JqvXS4yX+PtJn5BuqoKkYav7I0g4nXcxRbGTomDwVQjFccOdyfYKpuPOHX/DqrPCcL+MIHrGVdP3bveUXlvdnA=="
+ "resolved": "2.9.3",
+ "contentHash": "/Kq28fCE7MjOV42YLVRAJzRF0WmEqsmflm0cfpMjGtzQ2lR5mYVj1/i0Y8uDAOLczkL3/jArrwehfMD0YogMAA=="
},
"xunit.core": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "hcODgS+RXdjmXq0zQzmRbERQgY+bAGGx1bdH3370t/8CTGmIEU2qAc1dQAjIRpARsacR0cj6LLJDUF5BNQNKTQ==",
+ "resolved": "2.9.3",
+ "contentHash": "BiAEvqGvyme19wE0wTKdADH+NloYqikiU0mcnmiNyXaF9HyHmE6sr/3DC5vnBkgsWaE6yPyWszKSPSApWdRVeQ==",
"dependencies": {
- "xunit.extensibility.core": "[2.7.1]",
- "xunit.extensibility.execution": "[2.7.1]"
+ "xunit.extensibility.core": "[2.9.3]",
+ "xunit.extensibility.execution": "[2.9.3]"
}
},
"xunit.extensibility.core": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "yLX4XlBFkvNYCzf+DEzlNk45KsSlu9W93IJHBmtUP96qZ9XyRYDFlwMj6BCcOhDKVNrZxSM8bqu4F/Qud4ehxA==",
+ "resolved": "2.9.3",
+ "contentHash": "kf3si0YTn2a8J8eZNb+zFpwfoyvIrQ7ivNk5ZYA5yuYk1bEtMe4DxJ2CF/qsRgmEnDr7MnW1mxylBaHTZ4qErA==",
"dependencies": {
"xunit.abstractions": "2.0.3"
}
},
"xunit.extensibility.execution": {
"type": "Transitive",
- "resolved": "2.7.1",
- "contentHash": "ei3dKF8agj4UKkJ6KkaZ5/Gcif3if6hBsyzegIQJonZDSKZFvb0AyKtyOhDfggBaXVL5iXZExITdRkfjC95yhw==",
+ "resolved": "2.9.3",
+ "contentHash": "yMb6vMESlSrE3Wfj7V6cjQ3S4TXdXpRqYeNEI3zsX31uTsGMJjEw6oD5F5u1cHnMptjhEECnmZSsPxB6ChZHDQ==",
"dependencies": {
- "xunit.extensibility.core": "[2.7.1]"
+ "xunit.extensibility.core": "[2.9.3]"
}
},
"sharpcompress": {
"type": "Project",
"dependencies": {
- "Microsoft.SourceLink.GitHub": "[8.0.0, )",
- "ZstdSharp.Port": "[0.7.6, )"
+ "System.Buffers": "[4.6.0, )",
+ "ZstdSharp.Port": "[0.8.4, )"
}
},
- "Microsoft.SourceLink.GitHub": {
+ "System.Buffers": {
"type": "CentralTransitive",
- "requested": "[8.0.0, )",
- "resolved": "8.0.0",
- "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==",
- "dependencies": {
- "Microsoft.Build.Tasks.Git": "8.0.0",
- "Microsoft.SourceLink.Common": "8.0.0"
- }
+ "requested": "[4.6.0, )",
+ "resolved": "4.6.0",
+ "contentHash": "lN6tZi7Q46zFzAbRYXTIvfXcyvQQgxnY7Xm6C6xQ9784dEL1amjM6S6Iw4ZpsvesAKnRVsM4scrDQaDqSClkjA=="
},
"ZstdSharp.Port": {
"type": "CentralTransitive",
- "requested": "[0.7.6, )",
- "resolved": "0.7.6",
- "contentHash": "opRgjMeBTNpZQyJaZOWCHGGpQ+d9T2Eg3q8JPeBj65srJBf1F3JidO2h7sYkK2s0Mcga+skrqypQY39CF8kcfA=="
+ "requested": "[0.8.4, )",
+ "resolved": "0.8.4",
+ "contentHash": "eieSXq3kakCUXbgdxkKaRqWS6hF0KBJcqok9LlDCs60GOyrynLvPOcQ0pRw7shdPF7lh/VepJ9cP9n9HHc759g=="
}
}
}
diff --git a/tests/TestArchives/Archives/7Zip.LZMA2.exe b/tests/TestArchives/Archives/7Zip.LZMA2.exe
new file mode 100644
index 00000000..889c8318
Binary files /dev/null and b/tests/TestArchives/Archives/7Zip.LZMA2.exe differ
diff --git a/tests/TestArchives/Archives/TarCorrupted.tar b/tests/TestArchives/Archives/TarCorrupted.tar
new file mode 100644
index 00000000..a21c4fe5
Binary files /dev/null and b/tests/TestArchives/Archives/TarCorrupted.tar differ
diff --git a/tests/TestArchives/Archives/Zip.implode.zip b/tests/TestArchives/Archives/Zip.implode.zip
new file mode 100644
index 00000000..bd4354f0
Binary files /dev/null and b/tests/TestArchives/Archives/Zip.implode.zip differ
diff --git a/tests/TestArchives/Archives/Zip.reduce1.zip b/tests/TestArchives/Archives/Zip.reduce1.zip
new file mode 100644
index 00000000..61af465b
Binary files /dev/null and b/tests/TestArchives/Archives/Zip.reduce1.zip differ
diff --git a/tests/TestArchives/Archives/Zip.reduce2.zip b/tests/TestArchives/Archives/Zip.reduce2.zip
new file mode 100644
index 00000000..c1bb8fdc
Binary files /dev/null and b/tests/TestArchives/Archives/Zip.reduce2.zip differ
diff --git a/tests/TestArchives/Archives/Zip.reduce3.zip b/tests/TestArchives/Archives/Zip.reduce3.zip
new file mode 100644
index 00000000..41773e57
Binary files /dev/null and b/tests/TestArchives/Archives/Zip.reduce3.zip differ
diff --git a/tests/TestArchives/Archives/Zip.reduce4.zip b/tests/TestArchives/Archives/Zip.reduce4.zip
new file mode 100644
index 00000000..d21129af
Binary files /dev/null and b/tests/TestArchives/Archives/Zip.reduce4.zip differ
diff --git a/tests/TestArchives/Archives/false.positive.tar b/tests/TestArchives/Archives/false.positive.tar
new file mode 100644
index 00000000..db91a2ff
Binary files /dev/null and b/tests/TestArchives/Archives/false.positive.tar differ