Loading libziparchive/include/ziparchive/zip_archive.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading libziparchive/zip_archive.cc +6 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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); } Loading @@ -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, Loading libziparchive/zip_archive_test.cc +87 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
libziparchive/include/ziparchive/zip_archive.h +3 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
libziparchive/zip_archive.cc +6 −4 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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); } Loading @@ -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, Loading
libziparchive/zip_archive_test.cc +87 −0 Original line number Diff line number Diff line Loading @@ -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); Loading