Treat no filters as an empty array in GetDecoderArray().

GetDecoderArray() will be used in an upcoming CL. It will be helpful to
differentiate between the lack of filters, which is valid, and invalid
filters.

Change-Id: I1a211d6222b4f613e662b4abc23c289fdd6e3693
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/67752
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_stream_acc.cpp b/core/fpdfapi/parser/cpdf_stream_acc.cpp
index cd99751..23c314f 100644
--- a/core/fpdfapi/parser/cpdf_stream_acc.cpp
+++ b/core/fpdfapi/parser/cpdf_stream_acc.cpp
@@ -137,7 +137,7 @@
 
   Optional<std::vector<std::pair<ByteString, const CPDF_Object*>>>
       decoder_array = GetDecoderArray(m_pStream->GetDict());
-  if (!decoder_array.has_value() ||
+  if (!decoder_array.has_value() || decoder_array.value().empty() ||
       !PDF_DataDecode({pSrcData.Get(), dwSrcSize}, estimated_size, bImageAcc,
                       decoder_array.value(), &pDecodedData, &dwDecodedSize,
                       &m_ImageDecoder, &m_pImageParam)) {
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index 1d19159..f1bcb28 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -367,7 +367,10 @@
 
 Optional<DecoderArray> GetDecoderArray(const CPDF_Dictionary* pDict) {
   const CPDF_Object* pFilter = pDict->GetDirectObjectFor("Filter");
-  if (!pFilter || (!pFilter->IsArray() && !pFilter->IsName()))
+  if (!pFilter)
+    return DecoderArray();
+
+  if (!pFilter->IsArray() && !pFilter->IsName())
     return pdfium::nullopt;
 
   const CPDF_Object* pParams =
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.h b/core/fpdfapi/parser/fpdf_parser_decode.h
index 3134e7c..d05092a 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.h
+++ b/core/fpdfapi/parser/fpdf_parser_decode.h
@@ -75,6 +75,11 @@
                           std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
                           uint32_t* dest_size);
 
+// Returns pdfium::nullopt if the filter in |pDict| is the wrong type or an
+// invalid decoder pipeline.
+// Returns an empty vector if there is no filter, or if the filter is an empty
+// array.
+// Otherwise, returns a vector of decoders.
 using DecoderArray = std::vector<std::pair<ByteString, const CPDF_Object*>>;
 Optional<DecoderArray> GetDecoderArray(const CPDF_Dictionary* pDict);
 
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index 91cb4f4..9c106b1 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -116,11 +116,11 @@
 // TODO(thestig): Test decoder params.
 TEST(fpdf_parser_decode, GetDecoderArray) {
   {
-    // No filter returns pdfium::nullopt.
-    // TODO(thestig): Should return empty DecoderArray instead.
+    // Treat no filter as an empty filter array.
     auto dict = pdfium::MakeRetain<CPDF_Dictionary>();
     Optional<DecoderArray> decoder_array = GetDecoderArray(dict.Get());
-    EXPECT_FALSE(decoder_array.has_value());
+    ASSERT_TRUE(decoder_array.has_value());
+    EXPECT_TRUE(decoder_array.value().empty());
   }
   {
     // Wrong filter type.