Allow ExtractToMemory to accept an empty buffer for empty entries
We don't actually need to extract the empty entries. Since the old code support extracting the empty entry to a empty buffer, add the support back in ExtractToMemory. Bug: 153393683 Test: unittests pass Change-Id: Idb9f0f4e6e4ffd4b44b80ddd3f54069bb7cedd7b
This commit is contained in:
parent
edf8335c72
commit
088c403e23
|
@ -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<MemoryWriter> 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<MemoryWriter>(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<FileWriter> 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<int64_t>(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<int64_t>(declared_length + current_offset), strerror(errno));
|
||||
return FileWriter{};
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return FileWriter(fd, declared_length);
|
||||
return std::unique_ptr<FileWriter>(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) {
|
||||
|
|
|
@ -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<uint32_t>(17), data.uncompressed_length);
|
||||
ASSERT_EQ(static_cast<uint32_t>(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<uint32_t>(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<uint32_t>(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<uint8_t>& zip_data,
|
|||
// "abdcdefghijk").
|
||||
ZipEntry64 entry;
|
||||
ASSERT_EQ(0, FindEntry(handle, "name", &entry));
|
||||
ASSERT_EQ(static_cast<uint32_t>(12), entry.uncompressed_length);
|
||||
ASSERT_EQ(12u, entry.uncompressed_length);
|
||||
|
||||
entry_out->resize(12);
|
||||
(*error_code_out) = ExtractToMemory(handle, &entry, &((*entry_out)[0]), 12);
|
||||
|
|
Loading…
Reference in New Issue