Loading libziparchive/zip_archive.cc +48 −13 Original line number Diff line number Diff line Loading @@ -848,6 +848,34 @@ class FileWriter : public Writer { size_t total_bytes_written_; }; class Reader { public: virtual bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const = 0; virtual ~Reader() {} protected: Reader() = default; private: DISALLOW_COPY_AND_ASSIGN(Reader); }; class EntryReader : public Reader { public: EntryReader(const MappedZipFile& zip_file, const ZipEntry* entry) : Reader(), zip_file_(zip_file), entry_(entry) {} virtual bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { return zip_file_.ReadAtOffset(buf, len, entry_->offset + offset); } virtual ~EntryReader() {} private: const MappedZipFile& zip_file_; const ZipEntry* entry_; }; // This method is using libz macros with old-style-casts #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" Loading @@ -856,8 +884,9 @@ static inline int zlib_inflateInit2(z_stream* stream, int window_bits) { } #pragma GCC diagnostic pop static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { static int32_t InflateReaderToWriter(const Reader& reader, const uint32_t compressed_length, const uint32_t uncompressed_length, Writer* writer, uint64_t* crc_out) { const size_t kBufSize = 32768; std::vector<uint8_t> read_buf(kBufSize); std::vector<uint8_t> write_buf(kBufSize); Loading Loading @@ -898,25 +927,23 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter); const uint32_t uncompressed_length = entry->uncompressed_length; uint64_t crc = 0; uint32_t compressed_length = entry->compressed_length; uint32_t remaining_bytes = compressed_length; do { /* read as much as we can */ if (zstream.avail_in == 0) { const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length; off64_t offset = entry->offset + (entry->compressed_length - compressed_length); const size_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes; const uint32_t offset = (compressed_length - remaining_bytes); // Make sure to read at offset to ensure concurrent access to the fd. if (!mapped_zip.ReadAtOffset(read_buf.data(), getSize, offset)) { ALOGW("Zip: inflate read failed, getSize = %zu: %s", getSize, strerror(errno)); if (!reader.ReadAtOffset(read_buf.data(), read_size, offset)) { ALOGW("Zip: inflate read failed, getSize = %zu: %s", read_size, strerror(errno)); return kIoError; } compressed_length -= getSize; remaining_bytes -= read_size; zstream.next_in = &read_buf[0]; zstream.avail_in = getSize; zstream.avail_in = read_size; } /* uncompress the data */ Loading Loading @@ -952,7 +979,7 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e // the same manner that we have above. *crc_out = crc; if (zstream.total_out != uncompressed_length || compressed_length != 0) { if (zstream.total_out != uncompressed_length || remaining_bytes != 0) { ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out, uncompressed_length); return kInconsistentInformation; Loading @@ -961,6 +988,14 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e return 0; } static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { const EntryReader reader(mapped_zip, entry); return InflateReaderToWriter(reader, entry->compressed_length, entry->uncompressed_length, writer, crc_out); } static int32_t CopyEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { static const uint32_t kBufSize = 32768; Loading Loading @@ -1118,7 +1153,7 @@ off64_t MappedZipFile::GetFileLength() const { } // Attempts to read |len| bytes into |buf| at offset |off|. bool MappedZipFile::ReadAtOffset(uint8_t* buf, size_t len, off64_t off) { bool MappedZipFile::ReadAtOffset(uint8_t* buf, size_t len, off64_t off) const { if (has_fd_) { if (!android::base::ReadFullyAtOffset(fd_, buf, len, off)) { ALOGE("Zip: failed to read at offset %" PRId64 "\n", off); Loading libziparchive/zip_archive_private.h +1 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ class MappedZipFile { off64_t GetFileLength() const; bool ReadAtOffset(uint8_t* buf, size_t len, off64_t off); bool ReadAtOffset(uint8_t* buf, size_t len, off64_t off) const; private: // If has_fd_ is true, fd is valid and we'll read contents of a zip archive Loading Loading
libziparchive/zip_archive.cc +48 −13 Original line number Diff line number Diff line Loading @@ -848,6 +848,34 @@ class FileWriter : public Writer { size_t total_bytes_written_; }; class Reader { public: virtual bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const = 0; virtual ~Reader() {} protected: Reader() = default; private: DISALLOW_COPY_AND_ASSIGN(Reader); }; class EntryReader : public Reader { public: EntryReader(const MappedZipFile& zip_file, const ZipEntry* entry) : Reader(), zip_file_(zip_file), entry_(entry) {} virtual bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const { return zip_file_.ReadAtOffset(buf, len, entry_->offset + offset); } virtual ~EntryReader() {} private: const MappedZipFile& zip_file_; const ZipEntry* entry_; }; // This method is using libz macros with old-style-casts #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" Loading @@ -856,8 +884,9 @@ static inline int zlib_inflateInit2(z_stream* stream, int window_bits) { } #pragma GCC diagnostic pop static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { static int32_t InflateReaderToWriter(const Reader& reader, const uint32_t compressed_length, const uint32_t uncompressed_length, Writer* writer, uint64_t* crc_out) { const size_t kBufSize = 32768; std::vector<uint8_t> read_buf(kBufSize); std::vector<uint8_t> write_buf(kBufSize); Loading Loading @@ -898,25 +927,23 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter); const uint32_t uncompressed_length = entry->uncompressed_length; uint64_t crc = 0; uint32_t compressed_length = entry->compressed_length; uint32_t remaining_bytes = compressed_length; do { /* read as much as we can */ if (zstream.avail_in == 0) { const size_t getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length; off64_t offset = entry->offset + (entry->compressed_length - compressed_length); const size_t read_size = (remaining_bytes > kBufSize) ? kBufSize : remaining_bytes; const uint32_t offset = (compressed_length - remaining_bytes); // Make sure to read at offset to ensure concurrent access to the fd. if (!mapped_zip.ReadAtOffset(read_buf.data(), getSize, offset)) { ALOGW("Zip: inflate read failed, getSize = %zu: %s", getSize, strerror(errno)); if (!reader.ReadAtOffset(read_buf.data(), read_size, offset)) { ALOGW("Zip: inflate read failed, getSize = %zu: %s", read_size, strerror(errno)); return kIoError; } compressed_length -= getSize; remaining_bytes -= read_size; zstream.next_in = &read_buf[0]; zstream.avail_in = getSize; zstream.avail_in = read_size; } /* uncompress the data */ Loading Loading @@ -952,7 +979,7 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e // the same manner that we have above. *crc_out = crc; if (zstream.total_out != uncompressed_length || compressed_length != 0) { if (zstream.total_out != uncompressed_length || remaining_bytes != 0) { ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out, uncompressed_length); return kInconsistentInformation; Loading @@ -961,6 +988,14 @@ static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* e return 0; } static int32_t InflateEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { const EntryReader reader(mapped_zip, entry); return InflateReaderToWriter(reader, entry->compressed_length, entry->uncompressed_length, writer, crc_out); } static int32_t CopyEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer, uint64_t* crc_out) { static const uint32_t kBufSize = 32768; Loading Loading @@ -1118,7 +1153,7 @@ off64_t MappedZipFile::GetFileLength() const { } // Attempts to read |len| bytes into |buf| at offset |off|. bool MappedZipFile::ReadAtOffset(uint8_t* buf, size_t len, off64_t off) { bool MappedZipFile::ReadAtOffset(uint8_t* buf, size_t len, off64_t off) const { if (has_fd_) { if (!android::base::ReadFullyAtOffset(fd_, buf, len, off)) { ALOGE("Zip: failed to read at offset %" PRId64 "\n", off); Loading
libziparchive/zip_archive_private.h +1 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ class MappedZipFile { off64_t GetFileLength() const; bool ReadAtOffset(uint8_t* buf, size_t len, off64_t off); bool ReadAtOffset(uint8_t* buf, size_t len, off64_t off) const; private: // If has_fd_ is true, fd is valid and we'll read contents of a zip archive Loading