diff options
author | 2015-09-11 14:44:53 +0000 | |
---|---|---|
committer | 2015-09-11 15:26:14 +0000 | |
commit | 4009d2c4938a768158d7ae2ea848933a96737d25 (patch) | |
tree | a9ef9f16d6b8c6d38e80d12b25d33ada88cb61af | |
parent | 3acb4fd79f961965057fd56dc6ab9dab3c0f9267 (diff) |
Add CRC-32 computation to third_party/ijar:zipper
This can be a problem for some usage of the produced ZIP file
to not compute the CRC-32 correctly. We still skip it for ijar
for speed.
--
MOS_MIGRATED_REVID=102844157
-rw-r--r-- | third_party/ijar/zip.cc | 35 | ||||
-rw-r--r-- | third_party/ijar/zip.h | 6 | ||||
-rw-r--r-- | third_party/ijar/zip_main.cc | 2 |
3 files changed, 31 insertions, 12 deletions
diff --git a/third_party/ijar/zip.cc b/third_party/ijar/zip.cc index cb9d1cc9d7..51e308de7d 100644 --- a/third_party/ijar/zip.cc +++ b/third_party/ijar/zip.cc @@ -213,7 +213,8 @@ class OutputZipFile : public ZipBuilder { virtual ~OutputZipFile() { Finish(); } virtual u1* NewFile(const char* filename, const u4 attr); - virtual int FinishFile(size_t filelength, bool compress = false); + virtual int FinishFile(size_t filelength, bool compress = false, + bool compute_crc = false); virtual int WriteEmptyFile(const char *filename); virtual size_t GetSize() { return Offset(q); @@ -235,6 +236,9 @@ class OutputZipFile : public ZipBuilder { // Compression method u2 compression_method; + // CRC32 + u4 crc32; + // external attributes field u4 external_attr; @@ -289,8 +293,10 @@ class OutputZipFile : public ZipBuilder { // Fill in the "compressed size" and "uncompressed size" fields in a local // file header previously written by WriteLocalFileHeader(). - size_t WriteFileSizeInLocalFileHeader(u1 *header_ptr, size_t out_length, - bool compress = false); + size_t WriteFileSizeInLocalFileHeader(u1 *header_ptr, + size_t out_length, + bool compress = false, + const u4 crc = 0); }; // @@ -760,6 +766,7 @@ int OutputZipFile::WriteEmptyFile(const char *filename) { LocalFileEntry *entry = new LocalFileEntry; entry->local_header_offset = Offset(q); entry->external_attr = 0; + entry->crc32 = 0; // Output the ZIP local_file_header: put_u4le(q, LOCAL_FILE_HEADER_SIGNATURE); @@ -768,7 +775,7 @@ int OutputZipFile::WriteEmptyFile(const char *filename) { put_u2le(q, 0); // compression_method put_u2le(q, 0); // last_mod_file_time put_u2le(q, 0); // last_mod_file_date - put_u4le(q, 0); // crc32 + put_u4le(q, entry->crc32); // crc32 put_u4le(q, 0); // compressed_size put_u4le(q, 0); // uncompressed_size put_u2le(q, file_name_length); @@ -800,7 +807,7 @@ void OutputZipFile::WriteCentralDirectory() { put_u2le(q, entry->compression_method); // compression method: put_u2le(q, 0); // last_mod_file_time put_u2le(q, 0); // last_mod_file_date - put_u4le(q, 0); // crc32 (jar/javac tools don't care) + put_u4le(q, entry->crc32); // crc32 put_u4le(q, entry->compressed_length); // compressed_size put_u4le(q, entry->uncompressed_length); // uncompressed_size put_u2le(q, entry->file_name_length); @@ -848,7 +855,7 @@ u1* OutputZipFile::WriteLocalFileHeader(const char* filename, const u4 attr) { put_u2le(q, COMPRESSION_METHOD_STORED); // compression method = placeholder put_u2le(q, 0); // last_mod_file_time put_u2le(q, 0); // last_mod_file_date - put_u4le(q, 0); // crc32 (jar/javac tools don't care) + put_u4le(q, entry->crc32); // crc32 put_u4le(q, 0); // compressed_size = placeholder put_u4le(q, 0); // uncompressed_size = placeholder put_u2le(q, entry->file_name_length); @@ -901,7 +908,8 @@ size_t TryDeflate(u1 *buf, size_t length) { size_t OutputZipFile::WriteFileSizeInLocalFileHeader(u1 *header_ptr, size_t out_length, - bool compress) { + bool compress, + const u4 crc) { size_t compressed_size = out_length; if (compress) { compressed_size = TryDeflate(q, out_length); @@ -912,7 +920,8 @@ size_t OutputZipFile::WriteFileSizeInLocalFileHeader(u1 *header_ptr, } else { put_u2le(header_ptr, COMPRESSION_METHOD_STORED); } - header_ptr += 8; + header_ptr += 4; + put_u4le(header_ptr, crc); // crc32 put_u4le(header_ptr, compressed_size); // compressed_size put_u4le(header_ptr, out_length); // uncompressed_size return compressed_size; @@ -937,9 +946,15 @@ u1* OutputZipFile::NewFile(const char* filename, const u4 attr) { return q; } -int OutputZipFile::FinishFile(size_t filelength, bool compress) { +int OutputZipFile::FinishFile(size_t filelength, bool compress, + bool compute_crc) { + u4 crc = 0; + if (compute_crc) { + crc = crc32(crc, q, filelength); + } size_t compressed_size = - WriteFileSizeInLocalFileHeader(header_ptr, filelength, compress); + WriteFileSizeInLocalFileHeader(header_ptr, filelength, compress, crc); + entries_.back()->crc32 = crc; entries_.back()->compressed_length = compressed_size; entries_.back()->uncompressed_length = filelength; if (compressed_size < filelength) { diff --git a/third_party/ijar/zip.h b/third_party/ijar/zip.h index c548cb3cdb..54a7a7c71c 100644 --- a/third_party/ijar/zip.h +++ b/third_party/ijar/zip.h @@ -63,8 +63,12 @@ class ZipBuilder { // Finish writing a file and specify its length. After calling this method // one should not reuse the pointer given by NewFile. The file can be // compressed using the deflate algorithm by setting `compress` to true. + // By default, CRC32 are not computed as java tooling doesn't care, but + // computing it can be activated by setting `compute_crc` to true. // On failure, returns -1 and GetError() will return an non-empty message. - virtual int FinishFile(size_t filelength, bool compress = false) = 0; + virtual int FinishFile(size_t filelength, + bool compress = false, + bool compute_crc = false) = 0; // Write an empty file, it is equivalent to: // NewFile(filename, 0); diff --git a/third_party/ijar/zip_main.cc b/third_party/ijar/zip_main.cc index 43b035ad97..4715032060 100644 --- a/third_party/ijar/zip_main.cc +++ b/third_party/ijar/zip_main.cc @@ -237,7 +237,7 @@ int create(char *zipfile, char **files, bool flatten, bool verbose, } memcpy(buffer, data, statst.st_size); munmap(data, statst.st_size); - builder->FinishFile(statst.st_size, compress); + builder->FinishFile(statst.st_size, compress, true); } } if (builder->Finish() < 0) { |