From 3f79edd31e37d74b31ebb9d505d654a8f7f27a1e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 07:53:28 +0000 Subject: [PATCH 1/5] Initial plan From d5a8f98500267dbf0467c086405761749520ad17 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 08:02:33 +0000 Subject: [PATCH 2/5] Fix async progress reporting for solid 7z extraction --- .../Archives/IAsyncArchiveExtensions.cs | 23 ++++++++++++++++--- .../SevenZip/SevenZipArchiveAsyncTests.cs | 22 ++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs b/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs index 4be1419f..534ef1ec 100644 --- a/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs +++ b/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs @@ -29,12 +29,29 @@ public static class IAsyncArchiveExtensions || archive.Type == ArchiveType.SevenZip ) { + var totalBytes = await archive.TotalUncompressedSizeAsync().ConfigureAwait(false); + var bytesRead = 0L; await using var reader = await archive .ExtractAllEntriesAsync() .ConfigureAwait(false); - await reader - .WriteAllToDirectoryAsync(destinationDirectory, options, cancellationToken) - .ConfigureAwait(false); + while (await reader.MoveToNextEntryAsync(cancellationToken).ConfigureAwait(false)) + { + cancellationToken.ThrowIfCancellationRequested(); + + await reader + .WriteEntryToDirectoryAsync(destinationDirectory, options, cancellationToken) + .ConfigureAwait(false); + + if (reader.Entry.IsDirectory) + { + continue; + } + + bytesRead += reader.Entry.Size; + progress?.Report( + new ProgressReport(reader.Entry.Key ?? string.Empty, bytesRead, totalBytes) + ); + } } else { diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs index b4f3c855..6c89c1db 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs @@ -1,9 +1,11 @@ +using System; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using SharpCompress.Archives; using SharpCompress.Archives.SevenZip; +using SharpCompress.Common; using SharpCompress.Readers; using SharpCompress.Test.Mocks; using Xunit; @@ -141,6 +143,26 @@ public class SevenZipArchiveAsyncTests : ArchiveTests VerifyFiles(); } + [Fact] + public async Task SevenZipArchive_Solid_WriteToDirectoryAsync_WithProgress() + { + var progressReports = new System.Collections.Generic.List(); + var progress = new Progress(report => progressReports.Add(report)); + var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z"); +#if NETFRAMEWORK + using var stream = File.OpenRead(testArchive); +#else + await using var stream = File.OpenRead(testArchive); +#endif + await using var archive = await ArchiveFactory.OpenAsyncArchive(new AsyncOnlyStream(stream)); + + await archive.WriteToDirectoryAsync(SCRATCH_FILES_PATH, progress: progress); + + await Task.Delay(1000); + VerifyFiles(); + Assert.True(progressReports.Count > 0, "Progress reports should be generated"); + } + [Fact] public async Task SevenZipArchive_BZip2_AsyncStreamExtraction() { From afea217934389d50e4c48844aaef0f1068cbacd1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 08:05:22 +0000 Subject: [PATCH 3/5] chore: finalize security verification --- src/SharpCompress/packages.lock.json | 12 ++++---- .../SharpCompress.AotSmoke/packages.lock.json | 28 ++++--------------- 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index e1e7afa5..05ccd77c 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -286,9 +286,9 @@ "net10.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.8, )", - "resolved": "10.0.8", - "contentHash": "dVbSXGIFNR5nZcv2tOLoWI+a9T4jtFd77IYjuND+QVe360qWgAF7H0WtoopYhRw/+SgpGUTyrkrh+65+ClNnfw==" + "requested": "[10.0.0, )", + "resolved": "10.0.0", + "contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -388,9 +388,9 @@ "net8.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[8.0.27, )", - "resolved": "8.0.27", - "contentHash": "rQi9TxifHRnXP7lVRZH05DxD2/XGbJp12q0ozcbrlBlBnyyzssFTH/2vLhtKWUp2CT1qVscTrcYTFiwTyKPKRg==" + "requested": "[8.0.22, )", + "resolved": "8.0.22", + "contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", diff --git a/tests/SharpCompress.AotSmoke/packages.lock.json b/tests/SharpCompress.AotSmoke/packages.lock.json index 74a5d802..33d459fa 100644 --- a/tests/SharpCompress.AotSmoke/packages.lock.json +++ b/tests/SharpCompress.AotSmoke/packages.lock.json @@ -4,15 +4,15 @@ "net10.0": { "Microsoft.DotNet.ILCompiler": { "type": "Direct", - "requested": "[10.0.6, )", - "resolved": "10.0.6", - "contentHash": "nBOzxOys8OeyJ+Nsi/uYlI/5TSsvwjaM/p5m4dTL6khCLx9UuP3b2ec3HeuBw/+F7hHCAZG1yFx8VBeoRAX+EQ==" + "requested": "[10.0.0, )", + "resolved": "10.0.0", + "contentHash": "f9u8fMRROe2lS5MOOLutK6iSNTK9pC3kqd90FIn8Sk29fbZ0QDjZrBbwUkhouk/8dppC71SIEQaag0lGRTxvfA==" }, "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.6, )", - "resolved": "10.0.6", - "contentHash": "QKuvS0LWX4fjFqeDkyM7Kqt8P3wYTiPD4nwU+9y59n0sCiG714fxDgbbN82vDnzq89AF/PiHl92TP2C4aFDUQA==" + "requested": "[10.0.0, )", + "resolved": "10.0.0", + "contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -63,22 +63,6 @@ "sharpcompress": { "type": "Project" } - }, - "net10.0/osx-arm64": { - "Microsoft.DotNet.ILCompiler": { - "type": "Direct", - "requested": "[10.0.6, )", - "resolved": "10.0.6", - "contentHash": "nBOzxOys8OeyJ+Nsi/uYlI/5TSsvwjaM/p5m4dTL6khCLx9UuP3b2ec3HeuBw/+F7hHCAZG1yFx8VBeoRAX+EQ==", - "dependencies": { - "runtime.osx-arm64.Microsoft.DotNet.ILCompiler": "10.0.6" - } - }, - "runtime.osx-arm64.Microsoft.DotNet.ILCompiler": { - "type": "Transitive", - "resolved": "10.0.6", - "contentHash": "+yovwOAlIpfIcH+ZWmLYXWTSWYJ93wcQxF/RVk+X4MXgLASeosCJYVLqP20g0cufKjoRqvCmnklR6y9Su3ORtA==" - } } } } \ No newline at end of file From ae8d983b722d63c8c87bf108bd6c97718e499604 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 29 May 2026 08:13:41 +0000 Subject: [PATCH 4/5] Fix flaky progress test by using synchronous IProgress implementation --- src/SharpCompress/packages.lock.json | 12 ++++++------ .../SevenZip/SevenZipArchiveAsyncTests.cs | 12 ++++++++++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/SharpCompress/packages.lock.json b/src/SharpCompress/packages.lock.json index 05ccd77c..e1e7afa5 100644 --- a/src/SharpCompress/packages.lock.json +++ b/src/SharpCompress/packages.lock.json @@ -286,9 +286,9 @@ "net10.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[10.0.0, )", - "resolved": "10.0.0", - "contentHash": "kICGrGYEzCNI3wPzfEXcwNHgTvlvVn9yJDhSdRK+oZQy4jvYH529u7O0xf5ocQKzOMjfS07+3z9PKRIjrFMJDA==" + "requested": "[10.0.8, )", + "resolved": "10.0.8", + "contentHash": "dVbSXGIFNR5nZcv2tOLoWI+a9T4jtFd77IYjuND+QVe360qWgAF7H0WtoopYhRw/+SgpGUTyrkrh+65+ClNnfw==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", @@ -388,9 +388,9 @@ "net8.0": { "Microsoft.NET.ILLink.Tasks": { "type": "Direct", - "requested": "[8.0.22, )", - "resolved": "8.0.22", - "contentHash": "MhcMithKEiyyNkD2ZfbDZPmcOdi0GheGfg8saEIIEfD/fol3iHmcV8TsZkD4ZYz5gdUuoX4YtlVySUU7Sxl9SQ==" + "requested": "[8.0.27, )", + "resolved": "8.0.27", + "contentHash": "rQi9TxifHRnXP7lVRZH05DxD2/XGbJp12q0ozcbrlBlBnyyzssFTH/2vLhtKWUp2CT1qVscTrcYTFiwTyKPKRg==" }, "Microsoft.NETFramework.ReferenceAssemblies": { "type": "Direct", diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs index 6c89c1db..859910f2 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs @@ -147,7 +147,7 @@ public class SevenZipArchiveAsyncTests : ArchiveTests public async Task SevenZipArchive_Solid_WriteToDirectoryAsync_WithProgress() { var progressReports = new System.Collections.Generic.List(); - var progress = new Progress(report => progressReports.Add(report)); + var progress = new SynchronousProgress(report => progressReports.Add(report)); var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z"); #if NETFRAMEWORK using var stream = File.OpenRead(testArchive); @@ -158,7 +158,6 @@ public class SevenZipArchiveAsyncTests : ArchiveTests await archive.WriteToDirectoryAsync(SCRATCH_FILES_PATH, progress: progress); - await Task.Delay(1000); VerifyFiles(); Assert.True(progressReports.Count > 0, "Progress reports should be generated"); } @@ -358,4 +357,13 @@ public class SevenZipArchiveAsyncTests : 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 } + + private sealed class SynchronousProgress : IProgress + { + private readonly Action _handler; + + public SynchronousProgress(Action handler) => _handler = handler; + + public void Report(T value) => _handler(value); + } } From d6efe32cda9ca43edf18c370dbc84a2a734805cf Mon Sep 17 00:00:00 2001 From: Adam Hathcock Date: Fri, 29 May 2026 09:25:52 +0100 Subject: [PATCH 5/5] fmt --- src/SharpCompress/Archives/IAsyncArchiveExtensions.cs | 6 +++++- .../SevenZip/SevenZipArchiveAsyncTests.cs | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs b/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs index 534ef1ec..e9fd9723 100644 --- a/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs +++ b/src/SharpCompress/Archives/IAsyncArchiveExtensions.cs @@ -39,7 +39,11 @@ public static class IAsyncArchiveExtensions cancellationToken.ThrowIfCancellationRequested(); await reader - .WriteEntryToDirectoryAsync(destinationDirectory, options, cancellationToken) + .WriteEntryToDirectoryAsync( + destinationDirectory, + options, + cancellationToken + ) .ConfigureAwait(false); if (reader.Entry.IsDirectory) diff --git a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs index 859910f2..d28b6d54 100644 --- a/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs +++ b/tests/SharpCompress.Test/SevenZip/SevenZipArchiveAsyncTests.cs @@ -147,14 +147,18 @@ public class SevenZipArchiveAsyncTests : ArchiveTests public async Task SevenZipArchive_Solid_WriteToDirectoryAsync_WithProgress() { var progressReports = new System.Collections.Generic.List(); - var progress = new SynchronousProgress(report => progressReports.Add(report)); + var progress = new SynchronousProgress(report => + progressReports.Add(report) + ); var testArchive = Path.Combine(TEST_ARCHIVES_PATH, "7Zip.solid.7z"); #if NETFRAMEWORK using var stream = File.OpenRead(testArchive); #else await using var stream = File.OpenRead(testArchive); #endif - await using var archive = await ArchiveFactory.OpenAsyncArchive(new AsyncOnlyStream(stream)); + await using var archive = await ArchiveFactory.OpenAsyncArchive( + new AsyncOnlyStream(stream) + ); await archive.WriteToDirectoryAsync(SCRATCH_FILES_PATH, progress: progress);