Fix the bspatch failure on an empty brotli stream

When we close the BrotliDecompressor, we check for
BrotliDecoderIsFinished(). This function may return false if we never
call BrotliDecoderDecompressStream(), leading to a failure in bspatch
in case of an empty brotli stream.

This CL fixes the issue by checking BrotliDecoderIsUsed() along with
IsFinished(). Since we have the compressed stream and the precomputed
uncompressed size in the patch; we need these checks to avoid unexpected
size mismatch.

Bug: 69472150
Test: unittest pass
Change-Id: Icf7b324836fa59fd3111ba91b03622215a0c8f5f
diff --git a/brotli_compressor_unittest.cc b/brotli_compressor_unittest.cc
index 079b985..38492e4 100644
--- a/brotli_compressor_unittest.cc
+++ b/brotli_compressor_unittest.cc
@@ -37,4 +37,19 @@
       decompressed_data);
 }
 
+TEST(BrotliCompressorTest, BrotliCompressorEmptyStream) {
+  uint8_t empty_buffer[] = {};
+  BrotliCompressor brotli_compressor;
+  EXPECT_TRUE(brotli_compressor.Write(empty_buffer, sizeof(empty_buffer)));
+  EXPECT_TRUE(brotli_compressor.Finish());
+
+  std::vector<uint8_t> compressed_data = brotli_compressor.GetCompressedData();
+
+  // Check that we can close the decompressor without errors.
+  BrotliDecompressor brotli_decompressor;
+  EXPECT_TRUE(brotli_decompressor.SetInputData(compressed_data.data(),
+                                               compressed_data.size()));
+  EXPECT_TRUE(brotli_decompressor.Close());
+}
+
 }  // namespace bsdiff
\ No newline at end of file
diff --git a/brotli_decompressor.cc b/brotli_decompressor.cc
index 683e391..f173a75 100644
--- a/brotli_decompressor.cc
+++ b/brotli_decompressor.cc
@@ -49,7 +49,12 @@
 }
 
 bool BrotliDecompressor::Close() {
-  if (!BrotliDecoderIsFinished(brotli_decoder_state_)) {
+  // In some cases, the brotli compressed stream could be empty. As a result,
+  // the function BrotliDecoderIsFinished() will return false because we never
+  // start the decompression. When that happens, we just destroy the decoder
+  // and return true.
+  if (BrotliDecoderIsUsed(brotli_decoder_state_) &&
+      !BrotliDecoderIsFinished(brotli_decoder_state_)) {
     LOG(ERROR) << "Unfinished brotli decoder." << endl;
     return false;
   }
diff --git a/patch_reader_unittest.cc b/patch_reader_unittest.cc
index 61b63b7..7fe3650 100644
--- a/patch_reader_unittest.cc
+++ b/patch_reader_unittest.cc
@@ -72,7 +72,6 @@
               std::back_inserter(*patch_data));
   }
 
-
   void VerifyPatch(const std::vector<uint8_t>& patch_data) {
     BsdiffPatchReader patch_reader;
     EXPECT_TRUE(patch_reader.Init(patch_data.data(), patch_data.size()));
@@ -108,7 +107,7 @@
   std::unique_ptr<CompressorInterface> extra_stream_{nullptr};
 };
 
-TEST_F(PatchReaderTest, BZ2PatchReaderLegacyFormatSmoke) {
+TEST_F(PatchReaderTest, PatchReaderLegacyFormatSmoke) {
   ctrl_stream_.reset(new BZ2Compressor());
   diff_stream_.reset(new BZ2Compressor());
   extra_stream_.reset(new BZ2Compressor());
@@ -123,7 +122,7 @@
   VerifyPatch(patch_data);
 }
 
-TEST_F(PatchReaderTest, BZ2PatchReaderNewFormatSmoke) {
+TEST_F(PatchReaderTest, PatchReaderNewFormatSmoke) {
   // Compress the data with one bz2 and two brotli compressors.
   ctrl_stream_.reset(new BZ2Compressor());
   diff_stream_.reset(new BrotliCompressor());