mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-11-15 17:02:03 +00:00
Fix empty and directory-only 7z archive finalization
This commit is contained in:
@@ -43,6 +43,8 @@ public partial class SevenZipWriter
|
||||
|
||||
private async ValueTask FinalizeArchiveAsync()
|
||||
{
|
||||
// Reserve the signature even when no file data was written.
|
||||
await EnsurePlaceholderWrittenAsync(CancellationToken.None).ConfigureAwait(false);
|
||||
var output = OutputStream.NotNull();
|
||||
|
||||
// Current position = end of packed data streams
|
||||
|
||||
@@ -193,6 +193,8 @@ public partial class SevenZipWriter : AbstractWriter
|
||||
|
||||
private void FinalizeArchive()
|
||||
{
|
||||
// Directory-only and empty archives never pass through Write().
|
||||
EnsurePlaceholderWritten();
|
||||
var output = OutputStream.NotNull();
|
||||
|
||||
// Current position = end of packed data streams
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using SharpCompress.Archives.SevenZip;
|
||||
using SharpCompress.Writers.SevenZip;
|
||||
using Xunit;
|
||||
|
||||
namespace SharpCompress.Test.SevenZip;
|
||||
|
||||
public class SevenZipWriterStreamlessTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public async Task SevenZipWriter_Streamless_ClosesOwnedStream(bool async)
|
||||
{
|
||||
using var output = new MemoryStream();
|
||||
var writer = new SevenZipWriter(
|
||||
output,
|
||||
new SevenZipWriterOptions { LeaveStreamOpen = false }
|
||||
);
|
||||
writer.WriteDirectory("dir", null);
|
||||
if (async)
|
||||
{
|
||||
await writer.DisposeAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Dispose();
|
||||
}
|
||||
Assert.False(output.CanRead);
|
||||
using var input = new MemoryStream(output.ToArray());
|
||||
using var archive = SevenZipArchive.OpenArchive(input);
|
||||
Assert.True(archive.Entries.Single().IsDirectory);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, false, 0)]
|
||||
[InlineData(false, true, 0)]
|
||||
[InlineData(true, false, 0)]
|
||||
[InlineData(true, true, 0)]
|
||||
[InlineData(false, false, 2)]
|
||||
[InlineData(false, true, 2)]
|
||||
[InlineData(true, false, 2)]
|
||||
[InlineData(true, true, 2)]
|
||||
public async Task SevenZipWriter_Streamless_RoundTrip(
|
||||
bool async,
|
||||
bool compressHeader,
|
||||
int directories
|
||||
)
|
||||
{
|
||||
using var output = new MemoryStream();
|
||||
var writer = new SevenZipWriter(
|
||||
output,
|
||||
new SevenZipWriterOptions { CompressHeader = compressHeader }
|
||||
);
|
||||
for (var i = 0; i < directories; i++)
|
||||
{
|
||||
if (async)
|
||||
{
|
||||
await writer.WriteDirectoryAsync($"dir{i}", null, CancellationToken.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteDirectory($"dir{i}", null);
|
||||
}
|
||||
}
|
||||
if (async)
|
||||
{
|
||||
await writer.DisposeAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Dispose();
|
||||
}
|
||||
|
||||
Assert.True(output.CanRead);
|
||||
var bytes = output.ToArray();
|
||||
var offset = System.BitConverter.ToUInt64(bytes, 12);
|
||||
var size = System.BitConverter.ToUInt64(bytes, 20);
|
||||
Assert.Equal((ulong)bytes.Length, 32 + offset + size);
|
||||
output.Position = 0;
|
||||
using var archive = SevenZipArchive.OpenArchive(output);
|
||||
var entries = archive.Entries.ToList();
|
||||
Assert.Equal(directories, entries.Count);
|
||||
Assert.All(entries, entry => Assert.True(entry.IsDirectory));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user