diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc index 8f9774f19..7658d5c2d 100644 --- a/libziparchive/zip_archive.cc +++ b/libziparchive/zip_archive.cc @@ -1009,19 +1009,17 @@ int32_t Next(void* cookie, ZipEntry64* data, std::string_view* name) { // the data appended to it. class MemoryWriter : public zip_archive::Writer { public: - static MemoryWriter Create(uint8_t* buf, size_t size, const ZipEntry64* entry) { + static std::unique_ptr Create(uint8_t* buf, size_t size, const ZipEntry64* entry) { const uint64_t declared_length = entry->uncompressed_length; if (declared_length > size) { ALOGW("Zip: file size %" PRIu64 " is larger than the buffer size %zu.", declared_length, size); - return MemoryWriter{nullptr, 0}; + return nullptr; } - return MemoryWriter(buf, size); + return std::unique_ptr(new MemoryWriter(buf, size)); } - bool IsValid() const { return buf_ != nullptr; } - virtual bool Append(uint8_t* buf, size_t buf_size) override { if (size_ < buf_size || bytes_written_ > size_ - buf_size) { ALOGW("Zip: Unexpected size %zu (declared) vs %zu (actual)", size_, @@ -1053,17 +1051,17 @@ class FileWriter : public zip_archive::Writer { // block device). // // Returns a valid FileWriter on success, |nullptr| if an error occurred. - static FileWriter Create(int fd, const ZipEntry64* entry) { + static std::unique_ptr Create(int fd, const ZipEntry64* entry) { const uint64_t declared_length = entry->uncompressed_length; const off64_t current_offset = lseek64(fd, 0, SEEK_CUR); if (current_offset == -1) { ALOGW("Zip: unable to seek to current location on fd %d: %s", fd, strerror(errno)); - return FileWriter{}; + return nullptr; } if (declared_length > SIZE_MAX || declared_length > INT64_MAX) { ALOGW("Zip: file size %" PRIu64 " is too large to extract.", declared_length); - return FileWriter{}; + return nullptr; } #if defined(__linux__) @@ -1081,7 +1079,7 @@ class FileWriter : public zip_archive::Writer { if (result == -1 && errno == ENOSPC) { ALOGW("Zip: unable to allocate %" PRIu64 " bytes at offset %" PRId64 ": %s", declared_length, static_cast(current_offset), strerror(errno)); - return FileWriter{}; + return nullptr; } } #endif // __linux__ @@ -1089,7 +1087,7 @@ class FileWriter : public zip_archive::Writer { struct stat sb; if (fstat(fd, &sb) == -1) { ALOGW("Zip: unable to fstat file: %s", strerror(errno)); - return FileWriter{}; + return nullptr; } // Block device doesn't support ftruncate(2). @@ -1098,11 +1096,11 @@ class FileWriter : public zip_archive::Writer { if (result == -1) { ALOGW("Zip: unable to truncate file to %" PRId64 ": %s", static_cast(declared_length + current_offset), strerror(errno)); - return FileWriter{}; + return nullptr; } } - return FileWriter(fd, declared_length); + return std::unique_ptr(new FileWriter(fd, declared_length)); } FileWriter(FileWriter&& other) noexcept @@ -1112,8 +1110,6 @@ class FileWriter : public zip_archive::Writer { other.fd_ = -1; } - bool IsValid() const { return fd_ != -1; } - virtual bool Append(uint8_t* buf, size_t buf_size) override { if (declared_length_ < buf_size || total_bytes_written_ > declared_length_ - buf_size) { ALOGW("Zip: Unexpected size %zu (declared) vs %zu (actual)", declared_length_, @@ -1365,11 +1361,11 @@ int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry* entry, uint8_t int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry64* entry, uint8_t* begin, size_t size) { auto writer = MemoryWriter::Create(begin, size, entry); - if (!writer.IsValid()) { + if (!writer) { return kIoError; } - return ExtractToWriter(archive, entry, &writer); + return ExtractToWriter(archive, entry, writer.get()); } int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry* entry, int fd) { @@ -1379,11 +1375,11 @@ int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry* entry, int int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry64* entry, int fd) { auto writer = FileWriter::Create(fd, entry); - if (!writer.IsValid()) { + if (!writer) { return kIoError; } - return ExtractToWriter(archive, entry, &writer); + return ExtractToWriter(archive, entry, writer.get()); } int GetFileDescriptor(const ZipArchiveHandle archive) { diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc index 3d4e58074..f5429be0d 100644 --- a/libziparchive/zip_archive_test.cc +++ b/libziparchive/zip_archive_test.cc @@ -344,8 +344,8 @@ TEST(ziparchive, FindEntry) { // Known facts about a.txt, from zipinfo -v. ASSERT_EQ(63, data.offset); ASSERT_EQ(kCompressDeflated, data.method); - ASSERT_EQ(static_cast(17), data.uncompressed_length); - ASSERT_EQ(static_cast(13), data.compressed_length); + ASSERT_EQ(17u, data.uncompressed_length); + ASSERT_EQ(13u, data.compressed_length); ASSERT_EQ(0x950821c5, data.crc32); ASSERT_EQ(static_cast(0x438a8005), data.mod_time); @@ -505,9 +505,12 @@ TEST(ziparchive, EmptyEntries) { ZipEntry64 entry; ASSERT_EQ(0, FindEntry(handle, "empty.txt", &entry)); - ASSERT_EQ(static_cast(0), entry.uncompressed_length); + ASSERT_EQ(0u, entry.uncompressed_length); + // Extraction to a 1 byte buffer should succeed. uint8_t buffer[1]; ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1)); + // Extraction to an empty buffer should succeed. + ASSERT_EQ(0, ExtractToMemory(handle, &entry, nullptr, 0)); TemporaryFile tmp_output_file; ASSERT_NE(-1, tmp_output_file.fd); @@ -782,7 +785,7 @@ static void ExtractEntryToMemory(const std::vector& zip_data, // "abdcdefghijk"). ZipEntry64 entry; ASSERT_EQ(0, FindEntry(handle, "name", &entry)); - ASSERT_EQ(static_cast(12), entry.uncompressed_length); + ASSERT_EQ(12u, entry.uncompressed_length); entry_out->resize(12); (*error_code_out) = ExtractToMemory(handle, &entry, &((*entry_out)[0]), 12);