From 547c7d9a0b6651ace0ade7849661ba6c20770ae6 Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 14 Sep 2017 10:41:28 +0100 Subject: [PATCH] DO NOT MERGE : Fix build breakage due to 2d516d2d46b1b1. Test: make Test: zip_archive_test Bug: 64211847 Change-Id: Ide48ce66542e152d88520dcd6abcd104e48137f6 --- libziparchive/zip_archive.cc | 50 +++++++++++++++---------------- libziparchive/zip_archive_test.cc | 16 ++++++---- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index d0ba3d48f..4fe563865 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -594,6 +594,29 @@ static int32_t MapCentralDirectory(int fd, const char* debug_file_name, return result; } +// Attempts to read |len| bytes into |buf| at offset |off|. +// +// This method uses pread64 on platforms that support it and +// lseek64 + read on platforms that don't. This implies that +// callers should not rely on the |fd| offset being incremented +// as a side effect of this call. +static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, + off64_t off) { +#ifdef HAVE_PREAD + return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off)); +#else + // The only supported platform that doesn't support pread at the moment + // is Windows. Only recent versions of windows support unix like forks, + // and even there the semantics are quite different. + if (lseek64(fd, off, SEEK_SET) != off) { + ALOGW("Zip: failed seek to offset %" PRId64, off); + return kIoError; + } + + return TEMP_FAILURE_RETRY(read(fd, buf, len)); +#endif // HAVE_PREAD +} + /* * Parses the Zip archive's Central Directory. Allocates and populates the * hash table. @@ -672,8 +695,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) { } uint32_t lfh_start_bytes; - if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast(&lfh_start_bytes), - sizeof(uint32_t), 0)) { + if (ReadAtOffset(archive->fd, reinterpret_cast(&lfh_start_bytes), + sizeof(uint32_t), 0) != sizeof(uint32_t)) { ALOGW("Zip: Unable to read header for entry at offset == 0."); return -1; } @@ -755,29 +778,6 @@ static int32_t UpdateEntryFromDataDescriptor(int fd, return 0; } -// Attempts to read |len| bytes into |buf| at offset |off|. -// -// This method uses pread64 on platforms that support it and -// lseek64 + read on platforms that don't. This implies that -// callers should not rely on the |fd| offset being incremented -// as a side effect of this call. -static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, - off64_t off) { -#ifdef HAVE_PREAD - return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off)); -#else - // The only supported platform that doesn't support pread at the moment - // is Windows. Only recent versions of windows support unix like forks, - // and even there the semantics are quite different. - if (lseek64(fd, off, SEEK_SET) != off) { - ALOGW("Zip: failed seek to offset %" PRId64, off); - return kIoError; - } - - return TEMP_FAILURE_RETRY(read(fd, buf, len)); -#endif // HAVE_PREAD -} - static int32_t FindEntry(const ZipArchive* archive, const int ent, ZipEntry* data) { const uint16_t nameLen = archive->hash_table[ent].name_length; diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 4088843f9..2ae49a22b 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -266,7 +266,7 @@ TEST(ziparchive, ExtractToFile) { // Manual changes : // [2] = 0xff // Corrupt the LFH signature of entry 0. // [3] = 0xff // Corrupt the LFH signature of entry 0. -static const std::vector kZipFileWithBrokenLfhSignature{ +static const uint8_t kZipFileWithBrokenLfhSignature[] = { //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- @@ -297,12 +297,16 @@ static const std::vector kZipFileWithBrokenLfhSignature{ 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; TEST(ziparchive, BrokenLfhSignature) { - TemporaryFile tmp_file; - ASSERT_NE(-1, tmp_file.fd); - ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], - kZipFileWithBrokenLfhSignature.size())); + char kTempFilePattern[] = "zip_archive_input_XXXXXX"; + int fd = make_temporary_file(kTempFilePattern); + ASSERT_NE(-1, fd); + + ASSERT_EQ(static_cast(sizeof(kZipFileWithBrokenLfhSignature)), + TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature, + sizeof(kZipFileWithBrokenLfhSignature)))); ZipArchiveHandle handle; - ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); + ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle)); + close(fd); } int main(int argc, char** argv) {