mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-15 21:22:53 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fddd102dc | ||
|
|
13fdb4d7ca | ||
|
|
cdb13da054 | ||
|
|
fb70f06fd4 | ||
|
|
31c6eb3b5c | ||
|
|
eb7e55ac7d | ||
|
|
c81e78b5bb | ||
|
|
fb707aa676 |
4
.github/workflows/nuget-release.yml
vendored
4
.github/workflows/nuget-release.yml
vendored
@@ -53,9 +53,9 @@ jobs:
|
||||
name: ${{ matrix.os }}-nuget-package
|
||||
path: artifacts/*.nupkg
|
||||
|
||||
# Push to NuGet.org using C# build target (Windows only, not on PRs)
|
||||
# Push to NuGet.org only for version tag pushes (Windows only)
|
||||
- name: Push to NuGet
|
||||
if: success() && matrix.os == 'windows-latest' && github.event_name != 'pull_request'
|
||||
if: success() && matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
|
||||
run: dotnet run --project build/build.csproj -- push-to-nuget
|
||||
env:
|
||||
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
|
||||
|
||||
@@ -164,6 +164,12 @@ public partial class SevenZipArchive : AbstractArchive<SevenZipArchiveEntry, Sev
|
||||
|
||||
var folder = entry.FilePart.Folder;
|
||||
|
||||
// If folder is null (empty stream entry), return empty stream
|
||||
if (folder is null)
|
||||
{
|
||||
return CreateEntryStream(Stream.Null);
|
||||
}
|
||||
|
||||
// Check if we're starting a new folder - dispose old folder stream if needed
|
||||
if (folder != _currentFolder)
|
||||
{
|
||||
|
||||
@@ -206,8 +206,22 @@ internal partial class SharpCompressStream : Stream, IStreamStack
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public override long Length =>
|
||||
_isPassthrough ? stream.Length : throw new NotSupportedException();
|
||||
public override long Length
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_isPassthrough)
|
||||
{
|
||||
return stream.Length;
|
||||
}
|
||||
|
||||
if (_ringBuffer is not null)
|
||||
{
|
||||
return _ringBuffer.Length;
|
||||
}
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
public override long Position
|
||||
{
|
||||
|
||||
@@ -216,9 +216,9 @@
|
||||
"net10.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[10.0.0, )",
|
||||
"resolved": "10.0.0",
|
||||
"contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA=="
|
||||
"requested": "[10.0.2, )",
|
||||
"resolved": "10.0.2",
|
||||
"contentHash": "sXdDtMf2qcnbygw9OdE535c2lxSxrZP8gO4UhDJ0xiJbl1wIqXS1OTcTDFTIJPOFd6Mhcm8gPEthqWGUxBsTqw=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
@@ -264,9 +264,9 @@
|
||||
"net8.0": {
|
||||
"Microsoft.NET.ILLink.Tasks": {
|
||||
"type": "Direct",
|
||||
"requested": "[8.0.22, )",
|
||||
"resolved": "8.0.22",
|
||||
"contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ=="
|
||||
"requested": "[8.0.23, )",
|
||||
"resolved": "8.0.23",
|
||||
"contentHash": "GqHiB1HbbODWPbY/lc5xLQH8siEEhNA0ptpJCC6X6adtAYNEzu5ZlqV3YHA3Gh7fuEwgA8XqVwMtH2KNtuQM1Q=="
|
||||
},
|
||||
"Microsoft.NETFramework.ReferenceAssemblies": {
|
||||
"type": "Direct",
|
||||
|
||||
@@ -35,7 +35,7 @@ public class RarBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task RarExtractArchiveApiAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_rarBytes);
|
||||
await using var archive = RarArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await RarArchive.OpenAsyncArchive(stream).ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
|
||||
@@ -36,7 +36,9 @@ public class SevenZipBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task SevenZipLzmaExtractAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_lzmaBytes);
|
||||
await using var archive = SevenZipArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await SevenZipArchive
|
||||
.OpenAsyncArchive(stream)
|
||||
.ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
@@ -60,7 +62,9 @@ public class SevenZipBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task SevenZipLzma2ExtractAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_lzma2Bytes);
|
||||
await using var archive = SevenZipArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await SevenZipArchive
|
||||
.OpenAsyncArchive(stream)
|
||||
.ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
@@ -85,7 +89,9 @@ public class SevenZipBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task SevenZipLzma2ExtractAsync_Reader()
|
||||
{
|
||||
using var stream = new MemoryStream(_lzma2Bytes);
|
||||
await using var archive = SevenZipArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await SevenZipArchive
|
||||
.OpenAsyncArchive(stream)
|
||||
.ConfigureAwait(false);
|
||||
await using var reader = await archive.ExtractAllEntriesAsync();
|
||||
while (await reader.MoveToNextEntryAsync().ConfigureAwait(false))
|
||||
{
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TarBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task TarExtractArchiveApiAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_tarBytes);
|
||||
await using var archive = TarArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await TarArchive.OpenAsyncArchive(stream).ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
@@ -91,7 +91,7 @@ public class TarBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task TarGzipExtractAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_tarGzBytes);
|
||||
await using var archive = TarArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await TarArchive.OpenAsyncArchive(stream).ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ZipBenchmarks : ArchiveBenchmarkBase
|
||||
public async Task ZipExtractArchiveApiAsync()
|
||||
{
|
||||
using var stream = new MemoryStream(_archiveBytes);
|
||||
await using var archive = ZipArchive.OpenAsyncArchive(stream);
|
||||
await using var archive = await ZipArchive.OpenAsyncArchive(stream).ConfigureAwait(false);
|
||||
await foreach (var entry in archive.EntriesAsync.Where(e => !e.IsDirectory))
|
||||
{
|
||||
await using var entryStream = await entry.OpenEntryStreamAsync().ConfigureAwait(false);
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using SharpCompress.Archives;
|
||||
using SharpCompress.Archives.SevenZip;
|
||||
using SharpCompress.Common;
|
||||
using SharpCompress.Common.SevenZip;
|
||||
using SharpCompress.Factories;
|
||||
using SharpCompress.Readers;
|
||||
using Xunit;
|
||||
@@ -344,4 +345,53 @@ public class SevenZipArchiveTests : ArchiveTests
|
||||
// The critical check: within a single folder, the stream should NEVER be recreated
|
||||
Assert.Equal(0, streamRecreationsWithinFolder); // Folder stream should remain the same for all entries in the same folder
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SevenZipArchive_EmptyStream_WriteToDirectory()
|
||||
{
|
||||
// This test specifically verifies that archives with empty-stream entries
|
||||
// (files with size 0 and no compressed data) can be extracted without throwing
|
||||
// NullReferenceException. This was previously failing because the folder was null
|
||||
// for empty-stream entries.
|
||||
var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.EmptyStream.7z");
|
||||
using var archive = SevenZipArchive.OpenArchive(testArchive);
|
||||
|
||||
var emptyStreamFileCount = 0;
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
if (!entry.IsDirectory)
|
||||
{
|
||||
// Verify this is actually an empty-stream entry (HasStream == false)
|
||||
var sevenZipEntry = entry as SevenZipEntry;
|
||||
if (sevenZipEntry?.FilePart.Header.HasStream == false)
|
||||
{
|
||||
emptyStreamFileCount++;
|
||||
}
|
||||
|
||||
// This should not throw NullReferenceException
|
||||
entry.WriteToDirectory(SCRATCH_FILES_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we actually tested empty-stream entries
|
||||
Assert.True(
|
||||
emptyStreamFileCount > 0,
|
||||
"Test archive should contain at least one empty-stream entry"
|
||||
);
|
||||
|
||||
// Verify that empty files were created
|
||||
var extractedFiles = Directory.GetFiles(
|
||||
SCRATCH_FILES_PATH,
|
||||
"*",
|
||||
SearchOption.AllDirectories
|
||||
);
|
||||
Assert.NotEmpty(extractedFiles);
|
||||
|
||||
// All extracted files should be empty (0 bytes)
|
||||
foreach (var file in extractedFiles)
|
||||
{
|
||||
var fileInfo = new FileInfo(file);
|
||||
Assert.Equal(0, fileInfo.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BIN
tests/TestArchives/Archives/7Zip.EmptyStream.7z
Normal file
BIN
tests/TestArchives/Archives/7Zip.EmptyStream.7z
Normal file
Binary file not shown.
Reference in New Issue
Block a user