mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 12:42:22 -04:00
Fix zip64 having invalid header
This commit is contained in:
parent
455e76ad73
commit
bd2c38b717
@ -106,7 +106,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ZipWriter {
|
public sealed class ZipWriter {
|
||||||
BinaryWriter w;
|
BinaryWriter writer;
|
||||||
Stream stream;
|
Stream stream;
|
||||||
byte[] buffer = new byte[81920];
|
byte[] buffer = new byte[81920];
|
||||||
|
|
||||||
@ -116,11 +116,12 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
int numEntries;
|
int numEntries;
|
||||||
long centralDirOffset, centralDirSize, zip64EndOffset;
|
long centralDirOffset, centralDirSize, zip64EndOffset;
|
||||||
const ushort ver_norm = 20, ver_zip64 = 45, zip64Extra = 28;
|
const ushort ver_norm = 20, ver_zip64 = 45;
|
||||||
|
const ushort zip64CentralExtra = 28, zip64LocalExtra = 20;
|
||||||
|
|
||||||
public ZipWriter(Stream stream) {
|
public ZipWriter(Stream stream) {
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
w = new BinaryWriter(stream);
|
writer = new BinaryWriter(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteEntry(Stream src, string file, bool compress) {
|
public void WriteEntry(Stream src, string file, bool compress) {
|
||||||
@ -129,7 +130,7 @@ namespace MCGalaxy {
|
|||||||
entry.LocalHeaderOffset = stream.Position;
|
entry.LocalHeaderOffset = stream.Position;
|
||||||
|
|
||||||
// leave some room to fill in header later
|
// leave some room to fill in header later
|
||||||
int headerSize = 30 + entry.Filename.Length + zip64Extra;
|
int headerSize = 30 + entry.Filename.Length + zip64LocalExtra;
|
||||||
stream.Write(buffer, 0, headerSize);
|
stream.Write(buffer, 0, headerSize);
|
||||||
|
|
||||||
// set bit flag for non-ascii filename
|
// set bit flag for non-ascii filename
|
||||||
@ -156,7 +157,7 @@ namespace MCGalaxy {
|
|||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
// turns out we didn't actually need zip64 extra field
|
// turns out we didn't actually need zip64 extra field
|
||||||
ZipEntry entry = entries[i];
|
ZipEntry entry = entries[i];
|
||||||
if (!zip64) entry.LocalHeaderOffset += zip64Extra;
|
if (!zip64) entry.LocalHeaderOffset += zip64LocalExtra;
|
||||||
|
|
||||||
stream.Seek(entry.LocalHeaderOffset, SeekOrigin.Begin);
|
stream.Seek(entry.LocalHeaderOffset, SeekOrigin.Begin);
|
||||||
WriteLocalFileRecord(entry);
|
WriteLocalFileRecord(entry);
|
||||||
@ -190,8 +191,9 @@ namespace MCGalaxy {
|
|||||||
|
|
||||||
|
|
||||||
void WriteLocalFileRecord(ZipEntry entry) {
|
void WriteLocalFileRecord(ZipEntry entry) {
|
||||||
ushort extraLen = (ushort)(zip64 ? zip64Extra : 0);
|
ushort extraLen = (ushort)(zip64 ? zip64LocalExtra : 0);
|
||||||
ushort version = zip64 ? ver_zip64 : ver_norm;
|
ushort version = zip64 ? ver_zip64 : ver_norm;
|
||||||
|
BinaryWriter w = writer;
|
||||||
ZipEntry copy = entry;
|
ZipEntry copy = entry;
|
||||||
if (zip64) entry.Reset();
|
if (zip64) entry.Reset();
|
||||||
|
|
||||||
@ -207,12 +209,18 @@ namespace MCGalaxy {
|
|||||||
w.Write(extraLen);
|
w.Write(extraLen);
|
||||||
|
|
||||||
w.Write(entry.Filename);
|
w.Write(entry.Filename);
|
||||||
if (zip64) WriteZip64ExtraField(copy, false);
|
if (!zip64) return;
|
||||||
|
w.Write((ushort)1);
|
||||||
|
|
||||||
|
w.Write((ushort)(zip64LocalExtra - 4));
|
||||||
|
w.Write(copy.UncompressedSize);
|
||||||
|
w.Write(copy.CompressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteCentralDirectoryRecord(ZipEntry entry) {
|
void WriteCentralDirectoryRecord(ZipEntry entry) {
|
||||||
ushort extraLen = (ushort)(zip64 ? zip64Extra : 0);
|
ushort extraLen = (ushort)(zip64 ? zip64CentralExtra : 0);
|
||||||
ushort version = zip64 ? ver_zip64 : ver_norm;
|
ushort version = zip64 ? ver_zip64 : ver_norm;
|
||||||
|
BinaryWriter w = writer;
|
||||||
ZipEntry copy = entry;
|
ZipEntry copy = entry;
|
||||||
if (zip64) entry.Reset();
|
if (zip64) entry.Reset();
|
||||||
|
|
||||||
@ -234,30 +242,27 @@ namespace MCGalaxy {
|
|||||||
w.Write((int)entry.LocalHeaderOffset);
|
w.Write((int)entry.LocalHeaderOffset);
|
||||||
|
|
||||||
w.Write(entry.Filename);
|
w.Write(entry.Filename);
|
||||||
if (zip64) WriteZip64ExtraField(copy, true);
|
if (!zip64) return;
|
||||||
}
|
w.Write((ushort)1);
|
||||||
|
|
||||||
void WriteZip64ExtraField(ZipEntry entry, bool offset) {
|
|
||||||
int len = zip64Extra - 4; // ignore header size
|
|
||||||
if (!offset) len -= 8;
|
|
||||||
|
|
||||||
w.Write((ushort)1); // mapping id
|
w.Write((ushort)(zip64CentralExtra - 4));
|
||||||
w.Write((ushort)len);
|
w.Write(copy.UncompressedSize);
|
||||||
w.Write(entry.UncompressedSize);
|
w.Write(copy.CompressedSize);
|
||||||
w.Write(entry.CompressedSize);
|
w.Write(copy.LocalHeaderOffset);
|
||||||
if (offset) w.Write(entry.LocalHeaderOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteLastModified() {
|
void WriteLastModified() {
|
||||||
int modTime = (now.Second / 2) | (now.Minute << 5) | (now.Hour << 11);
|
int modTime = (now.Second / 2) | (now.Minute << 5) | (now.Hour << 11);
|
||||||
int modDate = (now.Day) | (now.Month << 5) | ((now.Year - 1980) << 9);
|
int modDate = (now.Day) | (now.Month << 5) | ((now.Year - 1980) << 9);
|
||||||
w.Write((ushort)modTime);
|
writer.Write((ushort)modTime);
|
||||||
w.Write((ushort)modDate);
|
writer.Write((ushort)modDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteZip64EndOfCentralDirectoryRecord() {
|
void WriteZip64EndOfCentralDirectoryRecord() {
|
||||||
w.Write((uint)0x06064b50);
|
BinaryWriter w = writer;
|
||||||
const long zip64EndDataSize = (2 * 2) + (2 * 4) + (4 * 8);
|
const long zip64EndDataSize = (2 * 2) + (2 * 4) + (4 * 8);
|
||||||
|
|
||||||
|
w.Write((uint)0x06064b50);
|
||||||
w.Write(zip64EndDataSize);
|
w.Write(zip64EndDataSize);
|
||||||
w.Write(ver_zip64);
|
w.Write(ver_zip64);
|
||||||
w.Write(ver_zip64);
|
w.Write(ver_zip64);
|
||||||
@ -270,6 +275,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WriteZip64EndOfCentralDirectoryLocator() {
|
void WriteZip64EndOfCentralDirectoryLocator() {
|
||||||
|
BinaryWriter w = writer;
|
||||||
w.Write((uint)0x07064b50);
|
w.Write((uint)0x07064b50);
|
||||||
w.Write(0); // disk number of zip64 end of central directory
|
w.Write(0); // disk number of zip64 end of central directory
|
||||||
w.Write(zip64EndOffset);
|
w.Write(zip64EndOffset);
|
||||||
@ -277,6 +283,7 @@ namespace MCGalaxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WriteEndOfCentralDirectoryRecord() {
|
void WriteEndOfCentralDirectoryRecord() {
|
||||||
|
BinaryWriter w = writer;
|
||||||
w.Write(0x06054b50);
|
w.Write(0x06054b50);
|
||||||
w.Write((ushort)0); // disk number
|
w.Write((ushort)0); // disk number
|
||||||
w.Write((ushort)0); // disk number of start
|
w.Write((ushort)0); // disk number of start
|
||||||
|
Loading…
x
Reference in New Issue
Block a user