Prevent BsdiffStream from accepting a nullptr input sream

The BsdiffStream defined in puffpatch.cc can accept a nullptr stream with no
problem. This is problematic. This patch adds a factory function to
BsdiffFileStream to check if the incoming stream pointer is invalid, in which
case it will return nullptr. Also we check that the source and target streams
are created correctly.

This bug was found by the puffin_fuzzer

Bug: crbug.com/830156
Bug: crbug.com/831772
Test: unittests
Test: corpus test

Change-Id: Iad8b093166ef26e2649e14e7e78adee17a5b5557
diff --git a/src/puffpatch.cc b/src/puffpatch.cc
index 216dcbe..c975944 100644
--- a/src/puffpatch.cc
+++ b/src/puffpatch.cc
@@ -90,9 +90,14 @@
 
 class BsdiffStream : public bsdiff::FileInterface {
  public:
-  explicit BsdiffStream(UniqueStreamPtr stream) : stream_(std::move(stream)) {}
   ~BsdiffStream() override = default;
 
+  static std::unique_ptr<bsdiff::FileInterface> Create(UniqueStreamPtr stream) {
+    TEST_AND_RETURN_VALUE(stream, nullptr);
+    return std::unique_ptr<bsdiff::FileInterface>(
+        new BsdiffStream(std::move(stream)));
+  }
+
   bool Read(void* buf, size_t count, size_t* bytes_read) override {
     *bytes_read = 0;
     if (stream_->Read(buf, count)) {
@@ -123,6 +128,8 @@
   }
 
  private:
+  explicit BsdiffStream(UniqueStreamPtr stream) : stream_(std::move(stream)) {}
+
   UniqueStreamPtr stream_;
 
   DISALLOW_COPY_AND_ASSIGN(BsdiffStream);
@@ -150,14 +157,15 @@
   auto huffer = std::make_shared<Huffer>();
 
   // For reading from source.
-  std::unique_ptr<bsdiff::FileInterface> reader(new BsdiffStream(
+  auto reader = BsdiffStream::Create(
       PuffinStream::CreateForPuff(std::move(src), puffer, src_puff_size,
-                                  src_deflates, src_puffs, max_cache_size)));
+                                  src_deflates, src_puffs, max_cache_size));
+  TEST_AND_RETURN_FALSE(reader);
 
   // For writing into destination.
-  std::unique_ptr<bsdiff::FileInterface> writer(
-      new BsdiffStream(PuffinStream::CreateForHuff(
-          std::move(dst), huffer, dst_puff_size, dst_deflates, dst_puffs)));
+  auto writer = BsdiffStream::Create(PuffinStream::CreateForHuff(
+      std::move(dst), huffer, dst_puff_size, dst_deflates, dst_puffs));
+  TEST_AND_RETURN_FALSE(writer);
 
   // Running bspatch itself.
   TEST_AND_RETURN_FALSE(0 == bspatch(reader, writer,