Skip to content

Commit

Permalink
Fix exports containing zero byte files after import from specific ZIP…
Browse files Browse the repository at this point in the history
… archives

Closes #27540.

As it turns out, some ZIP archivers (like 7zip) will decide to add fake
entries for directories, and some (like windows zipfolders) won't.
The "directory" entries aren't really properly supported using any
actual data or attributes, they're detected by sharpcompress basically
by heuristics:

    https://github.com/adamhathcock/sharpcompress/blob/ab5535eba365ec8fae58f92d53763ddf2dbf45af/src/SharpCompress/Common/Zip/Headers/ZipFileEntry.cs#L19-L31

When importing into realm we have thus far presumed that these directory
entries will not be a thing. Having them be a thing breaks multiple
things, like:

- When importing from ZIPs with separate directory entries, a separate
  `RealmFile` is created for a directory entry even though it doesn't
  represent a real file
- As a result, when re-exporting a model with files imported from such
  an archive, a zero-byte file would be created because to the database
  it looks like it was originally a zero-byte file.

If you want to have fun, google "zip empty directories". You'll see
a whole gamut of languages, libraries, and developers stepping on this
rake. Yet another episode of underspecced mistakes from decades ago
that were somebody's "good idea" but continue to wreak havoc forevermore
because now there are two competing conventions you can't just pick one.
  • Loading branch information
bdach committed Mar 12, 2024
1 parent 961058f commit 83e47b3
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion osu.Game/IO/Archives/ZipArchiveReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public override void Dispose()
archiveStream.Dispose();
}

public override IEnumerable<string> Filenames => archive.Entries.Select(e => e.Key).ExcludeSystemFileNames();
public override IEnumerable<string> Filenames => archive.Entries.Where(e => !e.IsDirectory).Select(e => e.Key).ExcludeSystemFileNames();

private class MemoryOwnerMemoryStream : Stream
{
Expand Down

0 comments on commit 83e47b3

Please sign in to comment.