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

Commit 55c9284f authored by Narayan Kamath's avatar Narayan Kamath Committed by Gerrit Code Review
Browse files

Merge "zip_archive: Allow crc_out to be nullptr in Inflate."

parents bb376934 2d1e23f5
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -265,6 +265,9 @@ class Reader {
 * Returns 0 on success and negative values on failure, for example if |reader|
 * cannot supply the right amount of data, or if the number of bytes written to
 * data does not match |uncompressed_length|.
 *
 * If |crc_out| is not nullptr, it is set to the crc32 checksum of the
 * uncompressed data.
 */
int32_t Inflate(const Reader& reader, const uint32_t compressed_length,
                const uint32_t uncompressed_length, Writer* writer, uint64_t* crc_out);
+6 −4
Original line number Diff line number Diff line
@@ -908,6 +908,7 @@ int32_t Inflate(const Reader& reader, const uint32_t compressed_length,

  std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);

  const bool compute_crc = (crc_out != nullptr);
  uint64_t crc = 0;
  uint32_t remaining_bytes = compressed_length;
  do {
@@ -939,9 +940,8 @@ int32_t Inflate(const Reader& reader, const uint32_t compressed_length,
    if (zstream.avail_out == 0 || (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
      const size_t write_size = zstream.next_out - &write_buf[0];
      if (!writer->Append(&write_buf[0], write_size)) {
        // The file might have declared a bogus length.
        return kInconsistentInformation;
      } else {
        return kIoError;
      } else if (compute_crc) {
        crc = crc32(crc, &write_buf[0], write_size);
      }

@@ -958,7 +958,9 @@ int32_t Inflate(const Reader& reader, const uint32_t compressed_length,
  // it ourselves above because there are no additional gains to be made by
  // having zlib calculate it for us, since they do it by calling crc32 in
  // the same manner that we have above.
  if (compute_crc) {
    *crc_out = crc;
  }

  if (zstream.total_out != uncompressed_length || remaining_bytes != 0) {
    ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out,
+87 −0
Original line number Diff line number Diff line
@@ -717,6 +717,93 @@ TEST(ziparchive, ErrorCodeString) {
  ASSERT_STREQ("I/O error", ErrorCodeString(kIoError));
}

class VectorReader : public zip_archive::Reader {
 public:
  VectorReader(const std::vector<uint8_t>& input) : Reader(), input_(input) {}

  bool ReadAtOffset(uint8_t* buf, size_t len, uint32_t offset) const {
    if ((offset + len) < input_.size()) {
      return false;
    }

    memcpy(buf, &input_[offset], len);
    return true;
  }

 private:
  const std::vector<uint8_t>& input_;
};

class VectorWriter : public zip_archive::Writer {
 public:
  VectorWriter() : Writer() {}

  bool Append(uint8_t* buf, size_t size) {
    output_.insert(output_.end(), buf, buf + size);
    return true;
  }

  std::vector<uint8_t>& GetOutput() { return output_; }

 private:
  std::vector<uint8_t> output_;
};

class BadReader : public zip_archive::Reader {
 public:
  BadReader() : Reader() {}

  bool ReadAtOffset(uint8_t*, size_t, uint32_t) const { return false; }
};

class BadWriter : public zip_archive::Writer {
 public:
  BadWriter() : Writer() {}

  bool Append(uint8_t*, size_t) { return false; }
};

TEST(ziparchive, Inflate) {
  const uint32_t compressed_length = kATxtContentsCompressed.size();
  const uint32_t uncompressed_length = kATxtContents.size();

  const VectorReader reader(kATxtContentsCompressed);
  {
    VectorWriter writer;
    uint64_t crc_out = 0;

    int32_t ret =
        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, &crc_out);
    ASSERT_EQ(0, ret);
    ASSERT_EQ(kATxtContents, writer.GetOutput());
    ASSERT_EQ(0x950821C5u, crc_out);
  }

  {
    VectorWriter writer;
    int32_t ret =
        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
    ASSERT_EQ(0, ret);
    ASSERT_EQ(kATxtContents, writer.GetOutput());
  }

  {
    BadWriter writer;
    int32_t ret =
        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
    ASSERT_EQ(kIoError, ret);
  }

  {
    BadReader reader;
    VectorWriter writer;
    int32_t ret =
        zip_archive::Inflate(reader, compressed_length, uncompressed_length, &writer, nullptr);
    ASSERT_EQ(kIoError, ret);
    ASSERT_EQ(0u, writer.GetOutput().size());
  }
}

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);