Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51de894c authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Allow ExtractToMemory to accept an empty buffer for empty entries"

parents 89cce058 088c403e
Loading
Loading
Loading
Loading
+14 −18
Original line number Diff line number Diff line
@@ -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) {
+7 −4
Original line number Diff line number Diff line
@@ -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);