Fix ZipArchiveEntry.ExtractToFile corruption when extraction fails with overwrite=true#123991
Fix ZipArchiveEntry.ExtractToFile corruption when extraction fails with overwrite=true#123991
Conversation
…lure Extract to temporary file when overwriting to avoid corrupting destination files if extraction fails (e.g., password-protected or corrupted archives). Add test to verify original file is preserved on extraction failure. Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
… catch exceptions Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
…n test Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
...ression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs
Show resolved
Hide resolved
...ression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs
Outdated
Show resolved
Hide resolved
...ression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs
Outdated
Show resolved
Hide resolved
….GetTempFileName, add ConfigureAwait(false) - Add FileOptions.Asynchronous to FileStreamOptions for async methods - Use Path.GetTempFileName() instead of same directory to avoid conflicts and ensure OS cleanup - Add ConfigureAwait(false) to await using statements in async method Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
|
Tagging subscribers to this area: @karelz, @dotnet/area-system-io-compression |
...O.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs
Outdated
Show resolved
Hide resolved
… directly Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This pull request fixes a critical bug where ZipArchiveEntry.ExtractToFile with overwrite: true corrupts destination files to 0 bytes when extraction fails. The fix implements a safe extraction strategy by extracting to a temporary file first, then atomically moving it to the destination only after successful extraction.
Changes:
- Modified extraction logic to use temporary files when overwriting existing files, preventing corruption on extraction failures
- Enhanced async implementation with proper
FileOptions.AsynchronousandConfigureAwait(false)usage - Added comprehensive test coverage to verify original files are preserved when extraction fails
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.cs | Implements temp-file-first extraction strategy for synchronous ExtractToFile, with proper cleanup on failure |
| src/libraries/System.IO.Compression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs | Implements temp-file-first extraction strategy for async ExtractToFileAsync, with proper async patterns and cleanup |
| src/libraries/System.IO.Compression.ZipFile/tests/ZipFileExtensions.ZipArchiveEntry.Extract.cs | Adds test that verifies original files are preserved when extraction fails due to corrupted archive data |
src/libraries/System.IO.Compression.ZipFile/tests/ZipFileExtensions.ZipArchiveEntry.Extract.cs
Show resolved
Hide resolved
src/libraries/System.IO.Compression.ZipFile/tests/ZipFileExtensions.ZipArchiveEntry.Extract.cs
Show resolved
Hide resolved
|
@copilot Address your comments |
Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
|
@copilot run the code review skill |
Code review complete. The PR is ready to merge. Summary: Implementation is correct and follows dotnet/runtime conventions. The temp-file-first approach properly solves the file corruption issue with appropriate error handling, async patterns, and test coverage. Key findings: Trade-off acknowledged: Using No blocking issues identified. |
...ression.ZipFile/src/System/IO/Compression/ZipFileExtensions.ZipArchiveEntry.Extract.Async.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: rzikm <32671551+rzikm@users.noreply.github.com>
Code Review: PR #123991Holistic AssessmentMotivation: Fixes a real data loss issue where Approach: Extract to a temporary file first (using Net positive: ✅ Yes - this is a solid defensive improvement that prevents data loss in a common failure scenario. Detailed Findings✅ Correctness
✅ Good Practices
|
|
/ba-g Test failures are unrelated |
1 similar comment
|
/ba-g Test failures are unrelated |
Fix: ZipArchiveEntry.ExtractToFile preserves files on extraction failure
Problem
When
ZipArchiveEntry.ExtractToFileis called withoverwrite: true, if extraction fails (e.g., password-protected or corrupted archive), the destination file is corrupted to 0 bytes because it was opened withFileMode.Createbefore callingsource.Open().Solution
Extract to a temporary file first when overwriting an existing file, and only move it to the destination path after successful extraction. If extraction fails, the temporary file is cleaned up and the original file remains intact.
Implementation Details
Synchronous (
ExtractToFile):overwriteis true and destination exists, extract to temp file first usingPath.GetTempFileName()Asynchronous (
ExtractToFileAsync):FileOptions.Asynchronousfor better async I/O performanceConfigureAwait(false)on all await operationsTemp File Strategy:
Path.GetTempFileName()for unique temp file in system temp directoryTesting
ExtractToFile_OverwritePreservesOriginalFileOnExtractionFailuretestInvalidDataExceptionChanges
ZipFileExtensions.ZipArchiveEntry.Extract.cs- Added temp file extraction logic and FileOptions supportZipFileExtensions.ZipArchiveEntry.Extract.Async.cs- Added async-optimized temp file extraction logicZipFileExtensions.ZipArchiveEntry.Extract.cs- Verifies original files are preserved on extraction failureSecurity
No security vulnerabilities introduced. This change improves robustness by preventing data loss when extraction fails.
Fixes #<issue_number>
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.