[Zucchini]: Write fuzz generated patches

As discussed in the tracking bug this covers buffer_sink and
patch_writer for fuzzing by serializing the generated patch data into a
buffer. Locally this increased fuzzing coverage by ~2%. exec/s for ZTF
files is still > 1500 which is sufficient for ClusterFuzz performance.

Eventually fuzzing should be added for:
- imposed_ensemble_matcher
- disassembler_dex

But is out of scope for Windows Launch.

It may also be worth adding an apply seed for a tiny Windows binary.
Chromium doesn't contain one small enough so we may need to make a
custom test binary to patch (likely Hello World or similar).

Bug: 835341
Change-Id: Id7208f30b09cd7443287cfe10f8ef1fcda6327d1
Reviewed-on: https://chromium-review.googlesource.com/1076949
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Max Moroz <mmoroz@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#563266}
NOKEYCHECK=True
GitOrigin-RevId: 49613c27bcd84170395588a6d93fc009eb988658
diff --git a/fuzzers/raw_gen_fuzzer.cc b/fuzzers/raw_gen_fuzzer.cc
index 176412d..b27042e 100644
--- a/fuzzers/raw_gen_fuzzer.cc
+++ b/fuzzers/raw_gen_fuzzer.cc
@@ -5,9 +5,11 @@
 #include <stdint.h>
 
 #include <iostream>
+#include <memory>
 
 #include "base/environment.h"
 #include "base/logging.h"
+#include "components/zucchini/buffer_sink.h"
 #include "components/zucchini/buffer_view.h"
 #include "components/zucchini/fuzzers/file_pair.pb.h"
 #include "components/zucchini/patch_writer.h"
@@ -16,14 +18,14 @@
 
 namespace {
 
-constexpr int kMinImageSize = 16;
-constexpr int kMaxImageSize = 1024;
+constexpr size_t kMinImageSize = 16;
+constexpr size_t kMaxImageSize = 1024;
 
 }  // namespace
 
 struct Environment {
   Environment() {
-    logging::SetMinLogLevel(3);  // Disable console spamming.
+    logging::SetMinLogLevel(logging::LOG_FATAL);  // Disable console spamming.
   }
 };
 
@@ -55,4 +57,15 @@
 
   // Fuzz Target.
   zucchini::GenerateRaw(old_image, new_image, &patch_writer);
+
+  // Check that the patch size is sane. Crash the fuzzer if this isn't the case
+  // as it is a failure in Zucchini's patch performance that is worth
+  // investigating.
+  size_t patch_size = patch_writer.SerializedSize();
+  CHECK_LE(patch_size, kMaxImageSize * 2);
+
+  // Write to buffer to avoid IO.
+  std::unique_ptr<uint8_t[]> patch_data(new uint8_t[patch_size]);
+  zucchini::BufferSink patch(patch_data.get(), patch_size);
+  patch_writer.SerializeInto(patch);
 }
diff --git a/fuzzers/ztf_gen_fuzzer.cc b/fuzzers/ztf_gen_fuzzer.cc
index 413d841..76ae44f 100644
--- a/fuzzers/ztf_gen_fuzzer.cc
+++ b/fuzzers/ztf_gen_fuzzer.cc
@@ -5,9 +5,11 @@
 #include <stdint.h>
 
 #include <iostream>
+#include <memory>
 
 #include "base/environment.h"
 #include "base/logging.h"
+#include "components/zucchini/buffer_sink.h"
 #include "components/zucchini/buffer_view.h"
 #include "components/zucchini/fuzzers/file_pair.pb.h"
 #include "components/zucchini/patch_writer.h"
@@ -16,8 +18,8 @@
 
 namespace {
 
-constexpr int kMinImageSize = 16;
-constexpr int kMaxImageSize = 1024;
+constexpr size_t kMinImageSize = 16;
+constexpr size_t kMaxImageSize = 1024;
 
 }  // namespace
 
@@ -56,4 +58,15 @@
 
   // Fuzz Target.
   zucchini::GenerateEnsemble(old_image, new_image, &patch_writer);
+
+  // Check that the patch size is sane. Crash the fuzzer if this isn't the case
+  // as it is a failure in Zucchini's patch performance that is worth
+  // investigating.
+  size_t patch_size = patch_writer.SerializedSize();
+  CHECK_LE(patch_size, kMaxImageSize * 2);
+
+  // Write to buffer to avoid IO.
+  std::unique_ptr<uint8_t[]> patch_data(new uint8_t[patch_size]);
+  zucchini::BufferSink patch(patch_data.get(), patch_size);
+  patch_writer.SerializeInto(patch);
 }