aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2015-09-11 14:44:53 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2015-09-11 15:26:14 +0000
commit4009d2c4938a768158d7ae2ea848933a96737d25 (patch)
treea9ef9f16d6b8c6d38e80d12b25d33ada88cb61af
parent3acb4fd79f961965057fd56dc6ab9dab3c0f9267 (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.cc35
-rw-r--r--third_party/ijar/zip.h6
-rw-r--r--third_party/ijar/zip_main.cc2
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) {