summaryrefslogtreecommitdiffstats
path: root/libziparchive
diff options
context:
space:
mode:
Diffstat (limited to 'libziparchive')
-rw-r--r--libziparchive/Android.mk3
-rw-r--r--libziparchive/zip_archive.cc150
2 files changed, 69 insertions, 84 deletions
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index ba7b74d..3937449 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -24,7 +24,8 @@ LOCAL_SRC_FILES := ${source_files}
LOCAL_STATIC_LIBRARIES := libz
LOCAL_SHARED_LIBRARIES := libutils
LOCAL_MODULE:= libziparchive
-LOCAL_CFLAGS := -Werror
+LOCAL_CFLAGS := -Werror -Wall
+LOCAL_CPPFLAGS := -Wold-style-cast
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index ebbab9f..59a1734 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -18,6 +18,8 @@
* Read-only access to Zip archives, with minimal heap allocation.
*/
+#include <memory>
+
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
@@ -293,7 +295,7 @@ struct ZipArchive {
/* mapped central directory area */
off64_t directory_offset;
- android::FileMap* directory_map;
+ android::FileMap directory_map;
/* number of entries in the Zip archive */
uint16_t num_entries;
@@ -311,7 +313,6 @@ struct ZipArchive {
fd(fd),
close_file(assume_ownership),
directory_offset(0),
- directory_map(NULL),
num_entries(0),
hash_table_size(0),
hash_table(NULL) {}
@@ -321,25 +322,10 @@ struct ZipArchive {
close(fd);
}
- delete directory_map;
free(hash_table);
}
};
-// Returns 0 on success and negative values on failure.
-static android::FileMap* MapFileSegment(const int fd, const off64_t start,
- const size_t length, const bool read_only,
- const char* debug_file_name) {
- android::FileMap* file_map = new android::FileMap;
- const bool success = file_map->create(debug_file_name, fd, start, length, read_only);
- if (!success) {
- delete file_map;
- return NULL;
- }
-
- return file_map;
-}
-
static int32_t CopyFileToFile(int fd, uint8_t* begin, const uint32_t length, uint64_t *crc_out) {
static const uint32_t kBufSize = 32768;
uint8_t buf[kBufSize];
@@ -521,16 +507,12 @@ static int32_t MapCentralDirectory0(int fd, const char* debug_file_name,
* It all looks good. Create a mapping for the CD, and set the fields
* in archive.
*/
- android::FileMap* map = MapFileSegment(fd,
- static_cast<off64_t>(eocd->cd_start_offset),
- static_cast<size_t>(eocd->cd_size),
- true /* read only */, debug_file_name);
- if (map == NULL) {
- archive->directory_map = NULL;
+ if (!archive->directory_map.create(debug_file_name, fd,
+ static_cast<off64_t>(eocd->cd_start_offset),
+ static_cast<size_t>(eocd->cd_size), true /* read only */) ) {
return kMmapFailed;
}
- archive->directory_map = map;
archive->num_entries = eocd->num_records;
archive->directory_offset = eocd->cd_start_offset;
@@ -557,7 +539,7 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name,
return kInvalidFile;
}
- if (file_length > (off64_t) 0xffffffff) {
+ if (file_length > static_cast<off64_t>(0xffffffff)) {
ALOGV("Zip: zip file too long %" PRId64, static_cast<int64_t>(file_length));
return kInvalidFile;
}
@@ -599,9 +581,9 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name,
* Returns 0 on success.
*/
static int32_t ParseZipArchive(ZipArchive* archive) {
- int32_t result = -1;
- const uint8_t* const cd_ptr = (const uint8_t*) archive->directory_map->getDataPtr();
- const size_t cd_length = archive->directory_map->getDataLength();
+ const uint8_t* const cd_ptr =
+ reinterpret_cast<const uint8_t*>(archive->directory_map.getDataPtr());
+ const size_t cd_length = archive->directory_map.getDataLength();
const uint16_t num_entries = archive->num_entries;
/*
@@ -610,8 +592,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
* least one unused entry to avoid an infinite loop during creation.
*/
archive->hash_table_size = RoundUpPower2(1 + (num_entries * 4) / 3);
- archive->hash_table = (ZipEntryName*) calloc(archive->hash_table_size,
- sizeof(ZipEntryName));
+ archive->hash_table = reinterpret_cast<ZipEntryName*>(calloc(archive->hash_table_size,
+ sizeof(ZipEntryName)));
/*
* Walk through the central directory, adding entries to the hash
@@ -624,18 +606,19 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
reinterpret_cast<const CentralDirectoryRecord*>(ptr);
if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
- goto bail;
+ return -1;
}
if (ptr + sizeof(CentralDirectoryRecord) > cd_end) {
ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
- goto bail;
+ return -1;
}
const off64_t local_header_offset = cdr->local_file_header_offset;
if (local_header_offset >= archive->directory_offset) {
- ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16, (int64_t)local_header_offset, i);
- goto bail;
+ ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16,
+ static_cast<int64_t>(local_header_offset), i);
+ return -1;
}
const uint16_t file_name_length = cdr->file_name_length;
@@ -645,7 +628,7 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
/* check that file name is valid UTF-8 and doesn't contain NUL (U+0000) characters */
if (!IsValidEntryName(file_name, file_name_length)) {
- goto bail;
+ return -1;
}
/* add the CDE filename to the hash table */
@@ -654,25 +637,21 @@ static int32_t ParseZipArchive(ZipArchive* archive) {
entry_name.name_length = file_name_length;
const int add_result = AddToHash(archive->hash_table,
archive->hash_table_size, entry_name);
- if (add_result) {
+ if (add_result != 0) {
ALOGW("Zip: Error adding entry to hash table %d", add_result);
- result = add_result;
- goto bail;
+ return add_result;
}
ptr += sizeof(CentralDirectoryRecord) + file_name_length + extra_length + comment_length;
if ((ptr - cd_ptr) > static_cast<int64_t>(cd_length)) {
ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16,
ptr - cd_ptr, cd_length, i);
- goto bail;
+ return -1;
}
}
ALOGV("+++ zip good scan %" PRIu16 " entries", num_entries);
- result = 0;
-
-bail:
- return result;
+ return 0;
}
static int32_t OpenArchiveInternal(ZipArchive* archive,
@@ -713,7 +692,7 @@ int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle) {
* Close a ZipArchive, closing the file and freeing the contents.
*/
void CloseArchive(ZipArchiveHandle handle) {
- ZipArchive* archive = (ZipArchive*) handle;
+ ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
ALOGV("Closing archive %p", archive);
delete archive;
}
@@ -774,8 +753,8 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent,
// the name that's in the hash table is a pointer to a location within
// this mapped region.
const uint8_t* base_ptr = reinterpret_cast<const uint8_t*>(
- archive->directory_map->getDataPtr());
- if (ptr < base_ptr || ptr > base_ptr + archive->directory_map->getDataLength()) {
+ archive->directory_map.getDataPtr());
+ if (ptr < base_ptr || ptr > base_ptr + archive->directory_map.getDataLength()) {
ALOGW("Zip: Invalid entry pointer");
return kInvalidOffset;
}
@@ -810,7 +789,8 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent,
ssize_t actual = ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf),
local_header_offset);
if (actual != sizeof(lfh_buf)) {
- ALOGW("Zip: failed reading lfh name from offset %" PRId64, (int64_t)local_header_offset);
+ ALOGW("Zip: failed reading lfh name from offset %" PRId64,
+ static_cast<int64_t>(local_header_offset));
return kIoError;
}
@@ -848,12 +828,12 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent,
return kInvalidOffset;
}
- uint8_t* name_buf = (uint8_t*) malloc(nameLen);
+ uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen));
ssize_t actual = ReadAtOffset(archive->fd, name_buf, nameLen,
name_offset);
if (actual != nameLen) {
- ALOGW("Zip: failed reading lfh name from offset %" PRId64, (int64_t)name_offset);
+ ALOGW("Zip: failed reading lfh name from offset %" PRId64, static_cast<int64_t>(name_offset));
free(name_buf);
return kIoError;
}
@@ -872,20 +852,21 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent,
const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader)
+ lfh->file_name_length + lfh->extra_field_length;
if (data_offset > cd_offset) {
- ALOGW("Zip: bad data offset %" PRId64 " in zip", (int64_t)data_offset);
+ ALOGW("Zip: bad data offset %" PRId64 " in zip", static_cast<int64_t>(data_offset));
return kInvalidOffset;
}
- if ((off64_t)(data_offset + data->compressed_length) > cd_offset) {
+ if (static_cast<off64_t>(data_offset + data->compressed_length) > cd_offset) {
ALOGW("Zip: bad compressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
- (int64_t)data_offset, data->compressed_length, (int64_t)cd_offset);
+ static_cast<int64_t>(data_offset), data->compressed_length, static_cast<int64_t>(cd_offset));
return kInvalidOffset;
}
if (data->method == kCompressStored &&
- (off64_t)(data_offset + data->uncompressed_length) > cd_offset) {
+ static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {
ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
- (int64_t)data_offset, data->uncompressed_length, (int64_t)cd_offset);
+ static_cast<int64_t>(data_offset), data->uncompressed_length,
+ static_cast<int64_t>(cd_offset));
return kInvalidOffset;
}
@@ -917,7 +898,7 @@ struct IterationHandle {
int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
const ZipEntryName* optional_prefix) {
- ZipArchive* archive = (ZipArchive *) handle;
+ ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
if (archive == NULL || archive->hash_table == NULL) {
ALOGW("Zip: Invalid ZipArchiveHandle");
@@ -939,7 +920,7 @@ void EndIteration(void* cookie) {
int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
ZipEntry* data) {
- const ZipArchive* archive = (ZipArchive*) handle;
+ const ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
if (entryName.name_length == 0) {
ALOGW("Zip: Invalid filename %.*s", entryName.name_length, entryName.name);
return kInvalidEntryName;
@@ -957,7 +938,7 @@ int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
}
int32_t Next(void* cookie, ZipEntry* data, ZipEntryName* name) {
- IterationHandle* handle = (IterationHandle *) cookie;
+ IterationHandle* handle = reinterpret_cast<IterationHandle*>(cookie);
if (handle == NULL) {
return kInvalidHandle;
}
@@ -991,10 +972,17 @@ int32_t Next(void* cookie, ZipEntry* data, ZipEntryName* name) {
return kIterationEnd;
}
+// This method is using libz macros with old-style-casts
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+static inline int zlib_inflateInit2(z_stream* stream, int window_bits) {
+ return inflateInit2(stream, window_bits);
+}
+#pragma GCC diagnostic pop
+
static int32_t InflateToFile(int fd, const ZipEntry* entry,
uint8_t* begin, uint32_t length,
uint64_t* crc_out) {
- int32_t result = -1;
const uint32_t kBufSize = 32768;
uint8_t read_buf[kBufSize];
uint8_t write_buf[kBufSize];
@@ -1010,7 +998,7 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
zstream.opaque = Z_NULL;
zstream.next_in = NULL;
zstream.avail_in = 0;
- zstream.next_out = (Bytef*) write_buf;
+ zstream.next_out = reinterpret_cast<Bytef*>(write_buf);
zstream.avail_out = kBufSize;
zstream.data_type = Z_UNKNOWN;
@@ -1018,7 +1006,7 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
* Use the undocumented "negative window bits" feature to tell zlib
* that there's no zlib header waiting for it.
*/
- zerr = inflateInit2(&zstream, -MAX_WBITS);
+ zerr = zlib_inflateInit2(&zstream, -MAX_WBITS);
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
ALOGE("Installed zlib is not compatible with linked version (%s)",
@@ -1030,6 +1018,12 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
return kZlibError;
}
+ auto zstream_deleter = [](z_stream* stream) {
+ inflateEnd(stream); /* free up any allocated structures */
+ };
+
+ std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
+
const uint32_t uncompressed_length = entry->uncompressed_length;
uint32_t compressed_length = entry->compressed_length;
@@ -1041,8 +1035,7 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, read_buf, getSize));
if (actual != getSize) {
ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize);
- result = kIoError;
- goto z_bail;
+ return kIoError;
}
compressed_length -= getSize;
@@ -1057,8 +1050,7 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
ALOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
zerr, zstream.next_in, zstream.avail_in,
zstream.next_out, zstream.avail_out);
- result = kZlibError;
- goto z_bail;
+ return kZlibError;
}
/* write when we're full or when we're done */
@@ -1067,7 +1059,7 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
const size_t write_size = zstream.next_out - write_buf;
// The file might have declared a bogus length.
if (write_size + write_count > length) {
- goto z_bail;
+ return -1;
}
memcpy(begin + write_count, write_buf, write_size);
write_count += write_size;
@@ -1085,26 +1077,20 @@ static int32_t InflateToFile(int fd, const ZipEntry* entry,
if (zstream.total_out != uncompressed_length || compressed_length != 0) {
ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")",
zstream.total_out, uncompressed_length);
- result = kInconsistentInformation;
- goto z_bail;
+ return kInconsistentInformation;
}
- result = 0;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
- return result;
+ return 0;
}
int32_t ExtractToMemory(ZipArchiveHandle handle,
ZipEntry* entry, uint8_t* begin, uint32_t size) {
- ZipArchive* archive = (ZipArchive*) handle;
+ ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
const uint16_t method = entry->method;
off64_t data_offset = entry->offset;
if (lseek64(archive->fd, data_offset, SEEK_SET) != data_offset) {
- ALOGW("Zip: lseek to data at %" PRId64 " failed", (int64_t)data_offset);
+ ALOGW("Zip: lseek to data at %" PRId64 " failed", static_cast<int64_t>(data_offset));
return kIoError;
}
@@ -1148,7 +1134,7 @@ int32_t ExtractEntryToFile(ZipArchiveHandle handle,
int result = TEMP_FAILURE_RETRY(ftruncate(fd, declared_length + current_offset));
if (result == -1) {
ALOGW("Zip: unable to truncate file to %" PRId64 ": %s",
- (int64_t)(declared_length + current_offset), strerror(errno));
+ static_cast<int64_t>(declared_length + current_offset), strerror(errno));
return kIoError;
}
@@ -1159,16 +1145,14 @@ int32_t ExtractEntryToFile(ZipArchiveHandle handle,
return 0;
}
- android::FileMap* map = MapFileSegment(fd, current_offset, declared_length,
- false, kTempMappingFileName);
- if (map == NULL) {
+ android::FileMap map;
+ if (!map.create(kTempMappingFileName, fd, current_offset, declared_length, false)) {
return kMmapFailed;
}
const int32_t error = ExtractToMemory(handle, entry,
- reinterpret_cast<uint8_t*>(map->getDataPtr()),
- map->getDataLength());
- delete map;
+ reinterpret_cast<uint8_t*>(map.getDataPtr()),
+ map.getDataLength());
return error;
}
@@ -1181,6 +1165,6 @@ const char* ErrorCodeString(int32_t error_code) {
}
int GetFileDescriptor(const ZipArchiveHandle handle) {
- return ((ZipArchive*) handle)->fd;
+ return reinterpret_cast<ZipArchive*>(handle)->fd;
}