mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-04 05:25:00 +00:00
Merge branch 'master' into dependabot/nuget/AwesomeAssertions-9.2.1
This commit is contained in:
@@ -144,6 +144,12 @@ public abstract class AbstractArchive<TEntry, TVolume> : IArchive, IArchiveExtra
|
||||
/// <returns></returns>
|
||||
public IReader ExtractAllEntries()
|
||||
{
|
||||
if (!IsSolid && Type != ArchiveType.SevenZip)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"ExtractAllEntries can only be used on solid archives or 7Zip archives (which require random access)."
|
||||
);
|
||||
}
|
||||
((IArchiveExtractionListener)this).EnsureEntriesLoaded();
|
||||
return CreateReaderForSolidExtraction();
|
||||
}
|
||||
|
||||
@@ -45,12 +45,10 @@ public static class IArchiveExtensions
|
||||
var seenDirectories = new HashSet<string>();
|
||||
|
||||
// Extract
|
||||
var entries = archive.ExtractAllEntries();
|
||||
while (entries.MoveToNextEntry())
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var entry = entries.Entry;
|
||||
if (entry.IsDirectory)
|
||||
{
|
||||
var dirPath = Path.Combine(destination, entry.Key.NotNull("Entry Key is null"));
|
||||
@@ -77,7 +75,7 @@ public static class IArchiveExtensions
|
||||
|
||||
// Write file
|
||||
using var fs = File.OpenWrite(path);
|
||||
entries.WriteEntryTo(fs);
|
||||
entry.WriteTo(fs);
|
||||
|
||||
// Update progress
|
||||
bytesRead += entry.Size;
|
||||
|
||||
@@ -1028,7 +1028,7 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
|
||||
vmCode.Add((byte)(GetBits() >> 8));
|
||||
AddBits(8);
|
||||
}
|
||||
return (AddVMCode(FirstByte, vmCode, Length));
|
||||
return AddVMCode(FirstByte, vmCode);
|
||||
}
|
||||
|
||||
private bool ReadVMCodePPM()
|
||||
@@ -1073,10 +1073,10 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
|
||||
}
|
||||
vmCode.Add((byte)Ch); // VMCode[I]=Ch;
|
||||
}
|
||||
return (AddVMCode(FirstByte, vmCode, Length));
|
||||
return AddVMCode(FirstByte, vmCode);
|
||||
}
|
||||
|
||||
private bool AddVMCode(int firstByte, List<byte> vmCode, int length)
|
||||
private bool AddVMCode(int firstByte, List<byte> vmCode)
|
||||
{
|
||||
var Inp = new BitInput();
|
||||
Inp.InitBitInput();
|
||||
@@ -1199,19 +1199,28 @@ internal sealed partial class Unpack : BitInput, IRarUnpack, IDisposable
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
Span<byte> VMCode = stackalloc byte[VMCodeSize];
|
||||
for (var I = 0; I < VMCodeSize; I++)
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
VMCode[I] = (byte)(Inp.GetBits() >> 8);
|
||||
Inp.AddBits(8);
|
||||
}
|
||||
|
||||
// VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
|
||||
rarVM.prepare(VMCode, VMCodeSize, Filter.Program);
|
||||
var VMCode = ArrayPool<byte>.Shared.Rent(VMCodeSize);
|
||||
try
|
||||
{
|
||||
for (var I = 0; I < VMCodeSize; I++)
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
|
||||
VMCode[I] = (byte)(Inp.GetBits() >> 8);
|
||||
Inp.AddBits(8);
|
||||
}
|
||||
|
||||
// VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
|
||||
rarVM.prepare(VMCode.AsSpan(0, VMCodeSize), Filter.Program);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(VMCode);
|
||||
}
|
||||
}
|
||||
StackFilter.Program.AltCommands = Filter.Program.Commands; // StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
|
||||
StackFilter.Program.CommandCount = Filter.Program.CommandCount;
|
||||
|
||||
@@ -776,9 +776,10 @@ internal sealed class RarVM : BitInput
|
||||
}
|
||||
}
|
||||
|
||||
public void prepare(ReadOnlySpan<byte> code, int codeSize, VMPreparedProgram prg)
|
||||
public void prepare(ReadOnlySpan<byte> code, VMPreparedProgram prg)
|
||||
{
|
||||
InitBitInput();
|
||||
var codeSize = code.Length;
|
||||
var cpLength = Math.Min(MAX_SIZE, codeSize);
|
||||
|
||||
// memcpy(inBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));
|
||||
@@ -795,7 +796,7 @@ internal sealed class RarVM : BitInput
|
||||
prg.CommandCount = 0;
|
||||
if (xorSum == code[0])
|
||||
{
|
||||
var filterType = IsStandardFilter(code, codeSize);
|
||||
var filterType = IsStandardFilter(code);
|
||||
if (filterType != VMStandardFilters.VMSF_NONE)
|
||||
{
|
||||
var curCmd = new VMPreparedCommand();
|
||||
@@ -1105,7 +1106,7 @@ internal sealed class RarVM : BitInput
|
||||
}
|
||||
}
|
||||
|
||||
private VMStandardFilters IsStandardFilter(ReadOnlySpan<byte> code, int codeSize)
|
||||
private VMStandardFilters IsStandardFilter(ReadOnlySpan<byte> code)
|
||||
{
|
||||
VMStandardFilterSignature[] stdList =
|
||||
{
|
||||
|
||||
@@ -40,6 +40,29 @@ public abstract class RarReader : AbstractReader<RarReaderEntry, RarVolume>
|
||||
|
||||
public override RarVolume? Volume => volume;
|
||||
|
||||
public static RarReader Open(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.CheckNotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), options);
|
||||
}
|
||||
|
||||
public static RarReader Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfo.OpenRead(), options);
|
||||
}
|
||||
|
||||
public static RarReader Open(IEnumerable<string> filePaths, ReaderOptions? options = null)
|
||||
{
|
||||
return Open(filePaths.Select(x => new FileInfo(x)), options);
|
||||
}
|
||||
|
||||
public static RarReader Open(IEnumerable<FileInfo> fileInfos, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfos.Select(x => x.OpenRead()), options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a RarReader for Non-seeking usage with a single volume
|
||||
/// </summary>
|
||||
|
||||
@@ -9,6 +9,18 @@ namespace SharpCompress.Readers;
|
||||
|
||||
public static class ReaderFactory
|
||||
{
|
||||
public static IReader Open(string filePath, ReaderOptions? options = null)
|
||||
{
|
||||
filePath.CheckNotNullOrEmpty(nameof(filePath));
|
||||
return Open(new FileInfo(filePath), options);
|
||||
}
|
||||
|
||||
public static IReader Open(FileInfo fileInfo, ReaderOptions? options = null)
|
||||
{
|
||||
options ??= new ReaderOptions { LeaveStreamOpen = false };
|
||||
return Open(fileInfo.OpenRead(), options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a Reader for Non-seeking usage
|
||||
/// </summary>
|
||||
|
||||
@@ -255,16 +255,10 @@ public class ArchiveTests : ReaderTests
|
||||
protected void ArchiveExtractToDirectory(
|
||||
string testArchive,
|
||||
ReaderOptions? readerOptions = null
|
||||
) => ArchiveExtractToDirectory(ArchiveFactory.AutoFactory, testArchive, readerOptions);
|
||||
|
||||
protected void ArchiveExtractToDirectory(
|
||||
IArchiveFactory archiveFactory,
|
||||
string testArchive,
|
||||
ReaderOptions? readerOptions = null
|
||||
)
|
||||
{
|
||||
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
|
||||
using (var archive = archiveFactory.Open(new FileInfo(testArchive), readerOptions))
|
||||
using (var archive = ArchiveFactory.Open(new FileInfo(testArchive), readerOptions))
|
||||
{
|
||||
archive.ExtractToDirectory(SCRATCH_FILES_PATH);
|
||||
}
|
||||
@@ -342,13 +336,12 @@ public class ArchiveTests : ReaderTests
|
||||
{
|
||||
testArchive = Path.Combine(TEST_ARCHIVES_PATH, testArchive);
|
||||
using var archive = ArchiveFactory.Open(testArchive);
|
||||
using var reader = archive.ExtractAllEntries();
|
||||
while (reader.MoveToNextEntry())
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
if (!reader.Entry.IsDirectory)
|
||||
if (!entry.IsDirectory)
|
||||
{
|
||||
var memory = new MemoryStream();
|
||||
reader.WriteEntryTo(memory);
|
||||
entry.WriteTo(memory);
|
||||
|
||||
memory.Position = 0;
|
||||
|
||||
|
||||
@@ -407,10 +407,16 @@ public class RarReaderTests : ReaderTests
|
||||
Path.Combine("exe", "test.exe"),
|
||||
}
|
||||
);
|
||||
using var archive = RarArchive.Open(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part01.rar")
|
||||
using var reader = RarReader.Open(
|
||||
[
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part01.rar"),
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part02.rar"),
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part03.rar"),
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part04.rar"),
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part05.rar"),
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Rar.multi.part06.rar"),
|
||||
]
|
||||
);
|
||||
using var reader = archive.ExtractAllEntries();
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
Assert.Equal(expectedOrder.Pop(), reader.Entry.Key);
|
||||
|
||||
@@ -734,8 +734,7 @@ public class ZipArchiveTests : ArchiveTests
|
||||
{
|
||||
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip");
|
||||
using var stream = File.OpenRead(zipPath);
|
||||
var archive = ArchiveFactory.Open(stream);
|
||||
var reader = archive.ExtractAllEntries();
|
||||
var reader = ReaderFactory.Open(stream);
|
||||
var entries = 0;
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -763,8 +762,7 @@ public class ZipArchiveTests : ArchiveTests
|
||||
};
|
||||
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.uncompressed.zip");
|
||||
using var stream = File.OpenRead(zipPath);
|
||||
var archive = ArchiveFactory.Open(stream);
|
||||
var reader = archive.ExtractAllEntries();
|
||||
var reader = ReaderFactory.Open(stream);
|
||||
var x = 0;
|
||||
while (reader.MoveToNextEntry())
|
||||
{
|
||||
@@ -781,7 +779,7 @@ public class ZipArchiveTests : ArchiveTests
|
||||
var zipPath = Path.Combine(TEST_ARCHIVES_PATH, "Zip.UnicodePathExtra.zip");
|
||||
using (var stream = File.OpenRead(zipPath))
|
||||
{
|
||||
var archive = ArchiveFactory.Open(
|
||||
var reader = ReaderFactory.Open(
|
||||
stream,
|
||||
new ReaderOptions
|
||||
{
|
||||
@@ -791,13 +789,12 @@ public class ZipArchiveTests : ArchiveTests
|
||||
},
|
||||
}
|
||||
);
|
||||
var reader = archive.ExtractAllEntries();
|
||||
reader.MoveToNextEntry();
|
||||
Assert.Equal("궖귛궖귙귪궖귗귪궖귙_wav.frq", reader.Entry.Key);
|
||||
}
|
||||
using (var stream = File.OpenRead(zipPath))
|
||||
{
|
||||
var archive = ArchiveFactory.Open(
|
||||
var reader = ReaderFactory.Open(
|
||||
stream,
|
||||
new ReaderOptions
|
||||
{
|
||||
@@ -807,7 +804,6 @@ public class ZipArchiveTests : ArchiveTests
|
||||
},
|
||||
}
|
||||
);
|
||||
var reader = archive.ExtractAllEntries();
|
||||
reader.MoveToNextEntry();
|
||||
Assert.Equal("きょきゅんきゃんきゅ_wav.frq", reader.Entry.Key);
|
||||
}
|
||||
|
||||
@@ -362,6 +362,8 @@ public class ZipReaderTests : ReaderTests
|
||||
while (reader.MoveToNextEntry()) { }
|
||||
}
|
||||
|
||||
//this test uses a large 7zip file containing a zip file inside it to test zip64 support
|
||||
// we probably shouldn't be allowing ExtractAllEntries here but it works for now.
|
||||
[Fact]
|
||||
public void Zip_Uncompressed_64bit()
|
||||
{
|
||||
@@ -383,11 +385,10 @@ public class ZipReaderTests : ReaderTests
|
||||
[Fact]
|
||||
public void Zip_Uncompressed_Encrypted_Read()
|
||||
{
|
||||
using var archive = ArchiveFactory.Open(
|
||||
using var reader = ReaderFactory.Open(
|
||||
Path.Combine(TEST_ARCHIVES_PATH, "Zip.none.encrypted.zip"),
|
||||
new ReaderOptions { Password = "test" }
|
||||
);
|
||||
using var reader = archive.ExtractAllEntries();
|
||||
reader.MoveToNextEntry();
|
||||
Assert.Equal("first.txt", reader.Entry.Key);
|
||||
Assert.Equal(199, reader.Entry.Size);
|
||||
|
||||
Reference in New Issue
Block a user