Loading libziparchive/zip_archive.cc +25 −25 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -672,8 +695,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) { } uint32_t lfh_start_bytes; if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0)) { if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0) != sizeof(uint32_t)) { ALOGW("Zip: Unable to read header for entry at offset == 0."); return -1; } Loading Loading @@ -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; Loading libziparchive/zip_archive_test.cc +10 −6 Original line number Diff line number Diff line Loading @@ -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<uint8_t> kZipFileWithBrokenLfhSignature{ static const uint8_t kZipFileWithBrokenLfhSignature[] = { //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- Loading Loading @@ -297,12 +297,16 @@ static const std::vector<uint8_t> 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<int32_t>(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) { Loading Loading
libziparchive/zip_archive.cc +25 −25 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -672,8 +695,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) { } uint32_t lfh_start_bytes; if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0)) { if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), sizeof(uint32_t), 0) != sizeof(uint32_t)) { ALOGW("Zip: Unable to read header for entry at offset == 0."); return -1; } Loading Loading @@ -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; Loading
libziparchive/zip_archive_test.cc +10 −6 Original line number Diff line number Diff line Loading @@ -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<uint8_t> kZipFileWithBrokenLfhSignature{ static const uint8_t kZipFileWithBrokenLfhSignature[] = { //[lfh-sig-----------], [lfh contents--------------------------------- 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, //-------------------------------------------------------------------- Loading Loading @@ -297,12 +297,16 @@ static const std::vector<uint8_t> 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<int32_t>(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) { Loading