From 6b151756108f57a1bc472ad121f27a38df2c80f0 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Tue, 8 Aug 2017 11:49:19 +0300 Subject: [PATCH] Fix Issue 2137 - Data not compressed on fly when adding to zip archive --- std/zip.d | 52 +++++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/std/zip.d b/std/zip.d index f27bbe0d6..762d62b48 100644 --- a/std/zip.d +++ b/std/zip.d @@ -360,11 +360,37 @@ final class ZipArchive { } - /** Add de to the archive. + /** Add de to the archive. The file is compressed on the fly. */ @safe void addMember(ArchiveMember de) { _directory[de.name] = de; + if (!de._compressedData.length) + { + switch (de.compressionMethod) + { + case CompressionMethod.none: + de._compressedData = de._expandedData; + break; + + case CompressionMethod.deflate: + import std.zlib : compress; + () @trusted + { + de._compressedData = cast(ubyte[]) compress(cast(void[]) de._expandedData); + }(); + de._compressedData = de._compressedData[2 .. de._compressedData.length - 4]; + break; + + default: + throw new ZipException("unsupported compression method"); + } + + de._compressedSize = to!uint(de._compressedData.length); + import std.zlib : crc32; + () @trusted { de._crc32 = crc32(0, cast(void[]) de._expandedData); }(); + } + assert(de._compressedData.length == de._compressedSize); } /** Delete de from the archive. @@ -399,30 +425,6 @@ final class ZipArchive auto directory = _directory.values().sort!((x, y) => x.index < y.index).release; foreach (ArchiveMember de; directory) { - if (!de._compressedData.length) - { - switch (de.compressionMethod) - { - case CompressionMethod.none: - de._compressedData = de._expandedData; - break; - - case CompressionMethod.deflate: - import std.zlib : compress; - de._compressedData = cast(ubyte[]) compress(cast(void[]) de._expandedData); - de._compressedData = de._compressedData[2 .. de._compressedData.length - 4]; - break; - - default: - throw new ZipException("unsupported compression method"); - } - - de._compressedSize = to!uint(de._compressedData.length); - import std.zlib : crc32; - de._crc32 = crc32(0, cast(void[]) de._expandedData); - } - assert(de._compressedData.length == de._compressedSize); - if (to!ulong(archiveSize) + 30 + de.name.length + de.extra.length + de.compressedSize + directorySize + 46 + de.name.length + de.extra.length + de.comment.length + 22 + comment.length + eocd64LocLength + eocd64Length > uint.max)