⚠⚠⚠ ZIP FILE CORRUPTION WHEN USING DIRECT MODE ⚠⚠⚠
まだ誰も着手していません。
評価
調査の方向性
src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs の 2861 行目付近から始め、直接モードでの BeginUpdate、delete、CommitUpdate 中に CopyEntryDirect を追跡します。小さい最初のファイルに続いて大きいファイルを配置し、その後最初のファイルを削除して再現します。この更新をコミットしても、ソースストリームと宛先ストリームが重なっている場合にアーカイブが破損しなくなれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Describe the bug
This looks to me like a somewhat big oversight - it silently corrupts files and no warning nor error happens until it is too late.
After a few hours of debugging I feel like CopyEntryDirect is simply not functional if, for instance, one of the first few files of the ZipFile got deleted in a prior operation.
Let's put it this way - in direct mode, source stream and destination stream are the same.
That means writing on the destination is the same as writing on the source. You want to make extra sure you don't write over what you're going to read next. But if any file is deleted, this premise is broken - as deletions are treated, and copies are treated first, upon trying to copy the file SharpZipLib will happily overwrite the very file it's reading with itself.
Let's take an example, for instance the one I just spent a while looking into. A zip file with a 44 byte file, and then a 80kB file.
I decide to delete the first one. It has an offset of zero, and the next file has an offset of 44, because it's right after.
BeginUpdate => Delete => CommitUpdate
Upon commitment, updates are sorted, and the copy will now happen before the delete.
So this is what the library does - it takes the first update it has to handle, it's a copy! From <offset 44> to <wherever we are>. Since we have not done anything yet, <wherever we are> is offset 0. So, CopyEntryDirect copies byte 44<=>80044 to 0<=>80000.
There is no alignment, so just writing the "header" of that file we're copying, which totals 75 bytes, already overwrites the file itself. This causes massive, unrecoverable wreckage onto any zip file it touches!
This could maybe fixed with some minimum alignment the size of a "maximum zip header", or maybe by accepting some level of fragmentation in files and not moving stuff onto itself, or maybe temporarily copying the stuff to memory before committing it to file (not like the Safe mode, which renews the stream completely, something I cannot do in my project)
Sorry for the very long issue but I felt like this was important.
Reproduction Code
No response
Steps to reproduce
Add a few files in a zip using ZipFile, start with a tiny one (~40 bytes), give a long name to the others, then delete the first one you added.
Expected behavior
Something else than complete archive corurption
Operating System
Windows
Framework Version
.NET Framework 4.x, Unity
Tags
ZIP
Additional context
No response
- 主要言語
- C#
- スター
- 3.9k
- フォーク
- 1k
- PR マージ指標
- 30日以内にマージされた PR はありません
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
icsharpcode/SharpZipLib のほかの issue
-
*no response* bug
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
icsharpcode/SharpZipLib#905 · コメント 1 件 ·
-
bug bzip2
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
icsharpcode/SharpZipLib#904 ·
-
SetLevel in ZipFile オープンenhancement zip
難易度 2/5 1〜2日 初心者へのやさしさ 55/100
icsharpcode/SharpZipLib#903 ·
-
*no response* bug
難易度 4/5 3〜5日 初心者へのやさしさ 32/100
icsharpcode/SharpZipLib#901 · コメント 1 件 ·
-
*no response* bug
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
icsharpcode/SharpZipLib#894 · コメント 1 件 ·
icsharpcode/SharpZipLib の issue をすべて見る
似ている issue
-
effort:S P3 refactor
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
nightscout/nocturne#1532 ·
-
core dependencies
難易度 1/5 1時間未満 初心者へのやさしさ 80/100
-
documentation
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
-
C#/.NET Roslyn LSP オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 75/100
DotNetNext/SqlSugar#1458 ·