diff options
author | Narayan Kamath | 2017-09-14 04:41:28 -0500 |
---|---|---|
committer | Narayan Kamath | 2017-09-14 11:58:32 -0500 |
commit | 547c7d9a0b6651ace0ade7849661ba6c20770ae6 (patch) | |
tree | 8a573418299aa741b13d9cca2596d5afe484d462 | |
parent | 64406ab149b9340938fe91b7cf6f3e95d4062ce0 (diff) | |
download | platform-system-core-547c7d9a0b6651ace0ade7849661ba6c20770ae6.tar.gz platform-system-core-547c7d9a0b6651ace0ade7849661ba6c20770ae6.tar.xz platform-system-core-547c7d9a0b6651ace0ade7849661ba6c20770ae6.zip |
DO NOT MERGE : Fix build breakage due to 2d516d2d46b1b1.
Test: make
Test: zip_archive_test
Bug: 64211847
Change-Id: Ide48ce66542e152d88520dcd6abcd104e48137f6
-rw-r--r-- | libziparchive/zip_archive.cc | 50 | ||||
-rw-r--r-- | 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, | |||
594 | return result; | 594 | return result; |
595 | } | 595 | } |
596 | 596 | ||
597 | // Attempts to read |len| bytes into |buf| at offset |off|. | ||
598 | // | ||
599 | // This method uses pread64 on platforms that support it and | ||
600 | // lseek64 + read on platforms that don't. This implies that | ||
601 | // callers should not rely on the |fd| offset being incremented | ||
602 | // as a side effect of this call. | ||
603 | static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, | ||
604 | off64_t off) { | ||
605 | #ifdef HAVE_PREAD | ||
606 | return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off)); | ||
607 | #else | ||
608 | // The only supported platform that doesn't support pread at the moment | ||
609 | // is Windows. Only recent versions of windows support unix like forks, | ||
610 | // and even there the semantics are quite different. | ||
611 | if (lseek64(fd, off, SEEK_SET) != off) { | ||
612 | ALOGW("Zip: failed seek to offset %" PRId64, off); | ||
613 | return kIoError; | ||
614 | } | ||
615 | |||
616 | return TEMP_FAILURE_RETRY(read(fd, buf, len)); | ||
617 | #endif // HAVE_PREAD | ||
618 | } | ||
619 | |||
597 | /* | 620 | /* |
598 | * Parses the Zip archive's Central Directory. Allocates and populates the | 621 | * Parses the Zip archive's Central Directory. Allocates and populates the |
599 | * hash table. | 622 | * hash table. |
@@ -672,8 +695,8 @@ static int32_t ParseZipArchive(ZipArchive* archive) { | |||
672 | } | 695 | } |
673 | 696 | ||
674 | uint32_t lfh_start_bytes; | 697 | uint32_t lfh_start_bytes; |
675 | if (!archive->mapped_zip.ReadAtOffset(reinterpret_cast<uint8_t*>(&lfh_start_bytes), | 698 | if (ReadAtOffset(archive->fd, reinterpret_cast<uint8_t*>(&lfh_start_bytes), |
676 | sizeof(uint32_t), 0)) { | 699 | sizeof(uint32_t), 0) != sizeof(uint32_t)) { |
677 | ALOGW("Zip: Unable to read header for entry at offset == 0."); | 700 | ALOGW("Zip: Unable to read header for entry at offset == 0."); |
678 | return -1; | 701 | return -1; |
679 | } | 702 | } |
@@ -755,29 +778,6 @@ static int32_t UpdateEntryFromDataDescriptor(int fd, | |||
755 | return 0; | 778 | return 0; |
756 | } | 779 | } |
757 | 780 | ||
758 | // Attempts to read |len| bytes into |buf| at offset |off|. | ||
759 | // | ||
760 | // This method uses pread64 on platforms that support it and | ||
761 | // lseek64 + read on platforms that don't. This implies that | ||
762 | // callers should not rely on the |fd| offset being incremented | ||
763 | // as a side effect of this call. | ||
764 | static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, | ||
765 | off64_t off) { | ||
766 | #ifdef HAVE_PREAD | ||
767 | return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off)); | ||
768 | #else | ||
769 | // The only supported platform that doesn't support pread at the moment | ||
770 | // is Windows. Only recent versions of windows support unix like forks, | ||
771 | // and even there the semantics are quite different. | ||
772 | if (lseek64(fd, off, SEEK_SET) != off) { | ||
773 | ALOGW("Zip: failed seek to offset %" PRId64, off); | ||
774 | return kIoError; | ||
775 | } | ||
776 | |||
777 | return TEMP_FAILURE_RETRY(read(fd, buf, len)); | ||
778 | #endif // HAVE_PREAD | ||
779 | } | ||
780 | |||
781 | static int32_t FindEntry(const ZipArchive* archive, const int ent, | 781 | static int32_t FindEntry(const ZipArchive* archive, const int ent, |
782 | ZipEntry* data) { | 782 | ZipEntry* data) { |
783 | const uint16_t nameLen = archive->hash_table[ent].name_length; | 783 | 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) { | |||
266 | // Manual changes : | 266 | // Manual changes : |
267 | // [2] = 0xff // Corrupt the LFH signature of entry 0. | 267 | // [2] = 0xff // Corrupt the LFH signature of entry 0. |
268 | // [3] = 0xff // Corrupt the LFH signature of entry 0. | 268 | // [3] = 0xff // Corrupt the LFH signature of entry 0. |
269 | static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{ | 269 | static const uint8_t kZipFileWithBrokenLfhSignature[] = { |
270 | //[lfh-sig-----------], [lfh contents--------------------------------- | 270 | //[lfh-sig-----------], [lfh contents--------------------------------- |
271 | 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, | 271 | 0x50, 0x4b, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, |
272 | //-------------------------------------------------------------------- | 272 | //-------------------------------------------------------------------- |
@@ -297,12 +297,16 @@ static const std::vector<uint8_t> kZipFileWithBrokenLfhSignature{ | |||
297 | 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; | 297 | 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00}; |
298 | 298 | ||
299 | TEST(ziparchive, BrokenLfhSignature) { | 299 | TEST(ziparchive, BrokenLfhSignature) { |
300 | TemporaryFile tmp_file; | 300 | char kTempFilePattern[] = "zip_archive_input_XXXXXX"; |
301 | ASSERT_NE(-1, tmp_file.fd); | 301 | int fd = make_temporary_file(kTempFilePattern); |
302 | ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, &kZipFileWithBrokenLfhSignature[0], | 302 | ASSERT_NE(-1, fd); |
303 | kZipFileWithBrokenLfhSignature.size())); | 303 | |
304 | ASSERT_EQ(static_cast<int32_t>(sizeof(kZipFileWithBrokenLfhSignature)), | ||
305 | TEMP_FAILURE_RETRY(write(fd, kZipFileWithBrokenLfhSignature, | ||
306 | sizeof(kZipFileWithBrokenLfhSignature)))); | ||
304 | ZipArchiveHandle handle; | 307 | ZipArchiveHandle handle; |
305 | ASSERT_EQ(-1, OpenArchiveFd(tmp_file.fd, "LeadingNonZipBytes", &handle)); | 308 | ASSERT_EQ(-1, OpenArchiveFd(fd, "LeadingNonZipBytes", &handle)); |
309 | close(fd); | ||
306 | } | 310 | } |
307 | 311 | ||
308 | int main(int argc, char** argv) { | 312 | int main(int argc, char** argv) { |