diff options
author | Yabin Cui | 2016-02-08 18:26:33 -0600 |
---|---|---|
committer | Yabin Cui | 2016-02-08 18:52:55 -0600 |
commit | 8e6f7227641e05dccfc29dad62e29e730ff8f5ca (patch) | |
tree | 8f869b06f61de44ef15c2e1430ba788b21f40c55 /libziparchive/zip_archive.cc | |
parent | d4ac11a57d37c56360e59ba75aa2f6ee777e5ed8 (diff) | |
download | platform-system-core-8e6f7227641e05dccfc29dad62e29e730ff8f5ca.tar.gz platform-system-core-8e6f7227641e05dccfc29dad62e29e730ff8f5ca.tar.xz platform-system-core-8e6f7227641e05dccfc29dad62e29e730ff8f5ca.zip |
libziparchive: port unit tests to darwin and windows.
Also use ReadFully to replace read, because read can
return reading bytes less than requested. And use
WriteFully to replace write.
Bug: 26962895
Change-Id: Iff0b2bc6d925619a537f7fef682c2a7ad89a2dc2
Diffstat (limited to 'libziparchive/zip_archive.cc')
-rw-r--r-- | libziparchive/zip_archive.cc | 51 |
1 files changed, 14 insertions, 37 deletions
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 3b1e972ce..a2d6fccd1 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc | |||
@@ -224,9 +224,7 @@ static int32_t MapCentralDirectory0(int fd, const char* debug_file_name, | |||
224 | strerror(errno)); | 224 | strerror(errno)); |
225 | return kIoError; | 225 | return kIoError; |
226 | } | 226 | } |
227 | ssize_t actual = TEMP_FAILURE_RETRY( | 227 | if (!android::base::ReadFully(fd, scan_buffer, static_cast<size_t>(read_amount))) { |
228 | read(fd, scan_buffer, static_cast<size_t>(read_amount))); | ||
229 | if (actual != static_cast<ssize_t>(read_amount)) { | ||
230 | ALOGW("Zip: read %" PRId64 " failed: %s", static_cast<int64_t>(read_amount), | 228 | ALOGW("Zip: read %" PRId64 " failed: %s", static_cast<int64_t>(read_amount), |
231 | strerror(errno)); | 229 | strerror(errno)); |
232 | return kIoError; | 230 | return kIoError; |
@@ -481,8 +479,7 @@ void CloseArchive(ZipArchiveHandle handle) { | |||
481 | static int32_t UpdateEntryFromDataDescriptor(int fd, | 479 | static int32_t UpdateEntryFromDataDescriptor(int fd, |
482 | ZipEntry *entry) { | 480 | ZipEntry *entry) { |
483 | uint8_t ddBuf[sizeof(DataDescriptor) + sizeof(DataDescriptor::kOptSignature)]; | 481 | uint8_t ddBuf[sizeof(DataDescriptor) + sizeof(DataDescriptor::kOptSignature)]; |
484 | ssize_t actual = TEMP_FAILURE_RETRY(read(fd, ddBuf, sizeof(ddBuf))); | 482 | if (!android::base::ReadFully(fd, ddBuf, sizeof(ddBuf))) { |
485 | if (actual != sizeof(ddBuf)) { | ||
486 | return kIoError; | 483 | return kIoError; |
487 | } | 484 | } |
488 | 485 | ||
@@ -498,26 +495,14 @@ static int32_t UpdateEntryFromDataDescriptor(int fd, | |||
498 | } | 495 | } |
499 | 496 | ||
500 | // Attempts to read |len| bytes into |buf| at offset |off|. | 497 | // Attempts to read |len| bytes into |buf| at offset |off|. |
501 | // | 498 | // Callers should not rely on the |fd| offset being incremented |
502 | // This method uses pread64 on platforms that support it and | ||
503 | // lseek64 + read on platforms that don't. This implies that | ||
504 | // callers should not rely on the |fd| offset being incremented | ||
505 | // as a side effect of this call. | 499 | // as a side effect of this call. |
506 | static inline ssize_t ReadAtOffset(int fd, uint8_t* buf, size_t len, | 500 | static inline bool ReadAtOffset(int fd, uint8_t* buf, size_t len, off64_t off) { |
507 | off64_t off) { | ||
508 | #if !defined(_WIN32) | ||
509 | return TEMP_FAILURE_RETRY(pread64(fd, buf, len, off)); | ||
510 | #else | ||
511 | // The only supported platform that doesn't support pread at the moment | ||
512 | // is Windows. Only recent versions of windows support unix like forks, | ||
513 | // and even there the semantics are quite different. | ||
514 | if (lseek64(fd, off, SEEK_SET) != off) { | 501 | if (lseek64(fd, off, SEEK_SET) != off) { |
515 | ALOGW("Zip: failed seek to offset %" PRId64, off); | 502 | ALOGW("Zip: failed seek to offset %" PRId64, off); |
516 | return kIoError; | 503 | return false; |
517 | } | 504 | } |
518 | 505 | return android::base::ReadFully(fd, buf, len); | |
519 | return TEMP_FAILURE_RETRY(read(fd, buf, len)); | ||
520 | #endif | ||
521 | } | 506 | } |
522 | 507 | ||
523 | static int32_t FindEntry(const ZipArchive* archive, const int ent, | 508 | static int32_t FindEntry(const ZipArchive* archive, const int ent, |
@@ -567,9 +552,7 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent, | |||
567 | } | 552 | } |
568 | 553 | ||
569 | uint8_t lfh_buf[sizeof(LocalFileHeader)]; | 554 | uint8_t lfh_buf[sizeof(LocalFileHeader)]; |
570 | ssize_t actual = ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf), | 555 | if (!ReadAtOffset(archive->fd, lfh_buf, sizeof(lfh_buf), local_header_offset)) { |
571 | local_header_offset); | ||
572 | if (actual != sizeof(lfh_buf)) { | ||
573 | ALOGW("Zip: failed reading lfh name from offset %" PRId64, | 556 | ALOGW("Zip: failed reading lfh name from offset %" PRId64, |
574 | static_cast<int64_t>(local_header_offset)); | 557 | static_cast<int64_t>(local_header_offset)); |
575 | return kIoError; | 558 | return kIoError; |
@@ -610,10 +593,7 @@ static int32_t FindEntry(const ZipArchive* archive, const int ent, | |||
610 | } | 593 | } |
611 | 594 | ||
612 | uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen)); | 595 | uint8_t* name_buf = reinterpret_cast<uint8_t*>(malloc(nameLen)); |
613 | ssize_t actual = ReadAtOffset(archive->fd, name_buf, nameLen, | 596 | if (!ReadAtOffset(archive->fd, name_buf, nameLen, name_offset)) { |
614 | name_offset); | ||
615 | |||
616 | if (actual != nameLen) { | ||
617 | ALOGW("Zip: failed reading lfh name from offset %" PRId64, static_cast<int64_t>(name_offset)); | 597 | ALOGW("Zip: failed reading lfh name from offset %" PRId64, static_cast<int64_t>(name_offset)); |
618 | free(name_buf); | 598 | free(name_buf); |
619 | return kIoError; | 599 | return kIoError; |
@@ -942,10 +922,9 @@ static int32_t InflateEntryToWriter(int fd, const ZipEntry* entry, | |||
942 | do { | 922 | do { |
943 | /* read as much as we can */ | 923 | /* read as much as we can */ |
944 | if (zstream.avail_in == 0) { | 924 | if (zstream.avail_in == 0) { |
945 | const ZD_TYPE getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length; | 925 | const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length; |
946 | const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, &read_buf[0], getSize)); | 926 | if (!android::base::ReadFully(fd, read_buf.data(), getSize)) { |
947 | if (actual != getSize) { | 927 | ALOGW("Zip: inflate read failed, getSize = %zu: %s", getSize, strerror(errno)); |
948 | ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize); | ||
949 | return kIoError; | 928 | return kIoError; |
950 | } | 929 | } |
951 | 930 | ||
@@ -1005,11 +984,9 @@ static int32_t CopyEntryToWriter(int fd, const ZipEntry* entry, Writer* writer, | |||
1005 | 984 | ||
1006 | // Safe conversion because kBufSize is narrow enough for a 32 bit signed | 985 | // Safe conversion because kBufSize is narrow enough for a 32 bit signed |
1007 | // value. | 986 | // value. |
1008 | const ssize_t block_size = (remaining > kBufSize) ? kBufSize : remaining; | 987 | const size_t block_size = (remaining > kBufSize) ? kBufSize : remaining; |
1009 | const ssize_t actual = TEMP_FAILURE_RETRY(read(fd, &buf[0], block_size)); | 988 | if (!android::base::ReadFully(fd, buf.data(), block_size)) { |
1010 | 989 | ALOGW("CopyFileToFile: copy read failed, block_size = %zu: %s", block_size, strerror(errno)); | |
1011 | if (actual != block_size) { | ||
1012 | ALOGW("CopyFileToFile: copy read failed (" ZD " vs " ZD ")", actual, block_size); | ||
1013 | return kIoError; | 990 | return kIoError; |
1014 | } | 991 | } |
1015 | 992 | ||