Merge "ZipWriter: Keep LFH and CFH in sync"
am: a309bc491d
Change-Id: I06f20c0edf1cc60bd39f38d45d512cfbf39bb0a9
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 0ac6f2c..246575f 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -563,6 +563,17 @@
// Paranoia: Match the values specified in the local file header
// to those specified in the central directory.
+
+ // Verify that the central directory and local file header agree on the use of a trailing
+ // Data Descriptor.
+ if ((lfh->gpb_flags & kGPBDDFlagMask) != (cdr->gpb_flags & kGPBDDFlagMask)) {
+ ALOGW("Zip: gpb flag mismatch. expected {%04" PRIx16 "}, was {%04" PRIx16 "}",
+ cdr->gpb_flags, lfh->gpb_flags);
+ return kInconsistentInformation;
+ }
+
+ // If there is no trailing data descriptor, verify that the central directory and local file
+ // header agree on the crc, compressed, and uncompressed sizes of the entry.
if ((lfh->gpb_flags & kGPBDDFlagMask) == 0) {
data->has_data_descriptor = 0;
if (data->compressed_length != lfh->compressed_size
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 2edf224..6d28bdb 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -479,7 +479,9 @@
for (FileEntry& file : files_) {
CentralDirectoryRecord cdr = {};
cdr.record_signature = CentralDirectoryRecord::kSignature;
- cdr.gpb_flags |= kGPBDDFlagMask;
+ if ((file.compression_method & kCompressDeflated) || !seekable_) {
+ cdr.gpb_flags |= kGPBDDFlagMask;
+ }
cdr.compression_method = file.compression_method;
cdr.last_mod_time = file.last_mod_time;
cdr.last_mod_date = file.last_mod_date;