Refractor the code for imgdiff
Put ImageChunk and some helper functions into a class. Also switch to
using std::vector instead of malloc.
Bug: 18606652
Test: imgdiff_test passed on host. Also generate a complete incremental OTA package.
The file content is the same and time consumption is similar.
Change-Id: Id603ada4e130ef521218400761a119001a86ca79
diff --git a/tests/Android.mk b/tests/Android.mk
index 3ab5ea6..9ee27a0 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -176,6 +176,7 @@
libbsdiff \
libbspatch \
libziparchive \
+ libutils \
libbase \
libcrypto \
libbz \
diff --git a/tests/component/imgdiff_test.cpp b/tests/component/imgdiff_test.cpp
index 7ad3307..be2dd38 100644
--- a/tests/component/imgdiff_test.cpp
+++ b/tests/component/imgdiff_test.cpp
@@ -236,6 +236,62 @@
ASSERT_EQ(tgt, patched);
}
+TEST(ImgdiffTest, zip_mode_smoke_trailer_zeros) {
+ // Construct src and tgt zip files.
+ TemporaryFile src_file;
+ FILE* src_file_ptr = fdopen(src_file.fd, "wb");
+ ZipWriter src_writer(src_file_ptr);
+ ASSERT_EQ(0, src_writer.StartEntry("file1.txt", ZipWriter::kCompress));
+ const std::string src_content("abcdefg");
+ ASSERT_EQ(0, src_writer.WriteBytes(src_content.data(), src_content.size()));
+ ASSERT_EQ(0, src_writer.FinishEntry());
+ ASSERT_EQ(0, src_writer.Finish());
+ ASSERT_EQ(0, fclose(src_file_ptr));
+
+ TemporaryFile tgt_file;
+ FILE* tgt_file_ptr = fdopen(tgt_file.fd, "wb");
+ ZipWriter tgt_writer(tgt_file_ptr);
+ ASSERT_EQ(0, tgt_writer.StartEntry("file1.txt", ZipWriter::kCompress));
+ const std::string tgt_content("abcdefgxyz");
+ ASSERT_EQ(0, tgt_writer.WriteBytes(tgt_content.data(), tgt_content.size()));
+ ASSERT_EQ(0, tgt_writer.FinishEntry());
+ ASSERT_EQ(0, tgt_writer.Finish());
+ // Add trailing zeros to the target zip file.
+ std::vector<uint8_t> zeros(10);
+ ASSERT_EQ(zeros.size(), fwrite(zeros.data(), sizeof(uint8_t), zeros.size(), tgt_file_ptr));
+ ASSERT_EQ(0, fclose(tgt_file_ptr));
+
+ // Compute patch.
+ TemporaryFile patch_file;
+ std::vector<const char*> args = {
+ "imgdiff", "-z", src_file.path, tgt_file.path, patch_file.path,
+ };
+ ASSERT_EQ(0, imgdiff(args.size(), args.data()));
+
+ // Verify.
+ std::string tgt;
+ ASSERT_TRUE(android::base::ReadFileToString(tgt_file.path, &tgt));
+ std::string src;
+ ASSERT_TRUE(android::base::ReadFileToString(src_file.path, &src));
+ std::string patch;
+ ASSERT_TRUE(android::base::ReadFileToString(patch_file.path, &patch));
+
+ // Expect three entries: CHUNK_RAW (header) + CHUNK_DEFLATE (data) + CHUNK_RAW (footer).
+ size_t num_normal;
+ size_t num_raw;
+ size_t num_deflate;
+ verify_patch_header(patch, &num_normal, &num_raw, &num_deflate);
+ ASSERT_EQ(0U, num_normal);
+ ASSERT_EQ(1U, num_deflate);
+ ASSERT_EQ(2U, num_raw);
+
+ std::string patched;
+ ASSERT_EQ(0, ApplyImagePatch(reinterpret_cast<const unsigned char*>(src.data()), src.size(),
+ reinterpret_cast<const unsigned char*>(patch.data()), patch.size(),
+ MemorySink, &patched));
+ ASSERT_EQ(tgt, patched);
+}
+
TEST(ImgdiffTest, image_mode_simple) {
// src: "abcdefgh" + gzipped "xyz" (echo -n "xyz" | gzip -f | hd).
const std::vector<char> src_data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g',