From 6a7f4bb79dde575d30af562af916b572b80ff9c3 Mon Sep 17 00:00:00 2001 From: Piotr Jastrzebski Date: Tue, 12 Aug 2014 10:26:17 +0100 Subject: [PATCH] Make sure that names of all entries have the same encoding. Add new public method to allow checkisc if an archive has entry names encoded in UTF-8. If not then they will be encoded in IBM PC character encoding. Bug: 16162465 Change-Id: I4468d76accca8a9b0b31cae8d43399ffc22cad42 --- include/ziparchive/zip_archive.h | 5 +++++ libziparchive/zip_archive.cc | 21 ++++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h index 27a97967d..afd2b7e54 100644 --- a/include/ziparchive/zip_archive.h +++ b/include/ziparchive/zip_archive.h @@ -157,6 +157,11 @@ int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name); */ void EndIteration(void* cookie); +/* + * Whether entry names in an archive are encoded in UTF-8. + */ +bool HasUTF8Names(const ZipArchiveHandle handle); + /* * Uncompress and write an entry to an open file identified by |fd|. * |entry->uncompressed_length| bytes will be written to the file at diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index a29eb79d8..9fe7cc7df 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -192,8 +192,11 @@ struct DataDescriptor { #undef DISALLOW_IMPLICIT_CONSTRUCTORS -static const uint32_t kGPBDDFlagMask = 0x0008; // mask value that signifies that the entry has a DD +// mask value that signifies that the entry has a DD +static const uint32_t kGPBDDFlagMask = 0x0008; static const uint32_t kMaxErrorLen = 1024; +// mask value that signifies that the entry names are encoded in UTF-8 +static const uint32_t kGPBEFSFlagMask = 0x0800; // The maximum size of a central directory or a file // comment in bytes. @@ -295,6 +298,7 @@ struct ZipArchive { /* number of entries in the Zip archive */ uint16_t num_entries; + bool utf8_names_encoding; /* * We know how many entries are in the Zip archive, so we can have a @@ -310,6 +314,7 @@ struct ZipArchive { directory_offset(0), directory_map(NULL), num_entries(0), + utf8_names_encoding(false), hash_table_size(0), hash_table(NULL) {} @@ -655,6 +660,15 @@ static int32_t ParseZipArchive(ZipArchive* archive) { ptr - cd_ptr, cd_length, i); goto bail; } + if (i == 0) { + archive->utf8_names_encoding = cdr->gpb_flags & kGPBEFSFlagMask; + } else { + bool has_utf8_name_encoding = cdr->gpb_flags & kGPBEFSFlagMask; + if (archive->utf8_names_encoding != has_utf8_name_encoding) { + ALOGW("Zip: Entry names encoded with different encoding"); + goto bail; + } + } } ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries); @@ -976,6 +990,11 @@ int32_t Next(void* cookie, ZipEntry* data, ZipEntryName* name) { return kIterationEnd; } +bool HasUTF8Names(const ZipArchiveHandle handle) { + const ZipArchive* archive = reinterpret_cast(handle); + return archive->utf8_names_encoding; +} + static int32_t InflateToFile(int fd, const ZipEntry* entry, uint8_t* begin, uint32_t length, uint64_t* crc_out) {