Support indirect objects for /Filter arrays
Other PDF viewers support using indirect references for /Filter arrays.
While not in the PDF spec, support indirect references as well.
Fixed: pdfium:1986
Change-Id: Ib92a9213bb8ec70523b041a120158aacdf7f4d43
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/104430
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Andy Phan <andyphan@chromium.org>
diff --git a/core/fpdfapi/parser/fpdf_parser_decode.cpp b/core/fpdfapi/parser/fpdf_parser_decode.cpp
index baf65f5..3e71a58 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode.cpp
@@ -94,8 +94,10 @@
return true;
for (size_t i = 0; i < count; ++i) {
- if (!pDecoders->GetObjectAt(i)->IsName())
+ RetainPtr<const CPDF_Object> object = pDecoders->GetDirectObjectAt(i);
+ if (!object || !object->IsName()) {
return false;
+ }
}
if (count == 1)
diff --git a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
index f88bf38..2c2074b 100644
--- a/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
+++ b/core/fpdfapi/parser/fpdf_parser_decode_unittest.cpp
@@ -8,7 +8,9 @@
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_indirect_object_holder.h"
#include "core/fpdfapi/parser/cpdf_name.h"
+#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fpdfapi/parser/cpdf_string.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -115,6 +117,62 @@
}
}
+TEST(ParserDecodeTest, ValidateDecoderPipelineWithIndirectObjects) {
+ {
+ // Valid 2 decoder pipeline with indirect objects.
+ CPDF_IndirectObjectHolder objects_holder;
+ auto decoder = pdfium::MakeRetain<CPDF_Name>(nullptr, "FlateDecode");
+ uint32_t decoder_number =
+ objects_holder.AddIndirectObject(std::move(decoder));
+
+ auto decoders = pdfium::MakeRetain<CPDF_Array>();
+ decoders->AppendNew<CPDF_Reference>(&objects_holder, decoder_number);
+ decoders->AppendNew<CPDF_Name>("LZW");
+ EXPECT_TRUE(ValidateDecoderPipeline(decoders.Get()));
+ }
+ {
+ // Valid 5 decoder pipeline with indirect objects, with an image decoder at
+ // the end.
+ CPDF_IndirectObjectHolder objects_holder;
+ auto decoder = pdfium::MakeRetain<CPDF_Name>(nullptr, "LZW");
+ uint32_t decoder_number =
+ objects_holder.AddIndirectObject(std::move(decoder));
+
+ auto decoders = pdfium::MakeRetain<CPDF_Array>();
+ decoders->AppendNew<CPDF_Name>("RunLengthDecode");
+ decoders->AppendNew<CPDF_Name>("ASCII85Decode");
+ decoders->AppendNew<CPDF_Name>("FlateDecode");
+ decoders->AppendNew<CPDF_Reference>(&objects_holder, decoder_number);
+ decoders->AppendNew<CPDF_Name>("DCTDecode");
+ EXPECT_TRUE(ValidateDecoderPipeline(decoders.Get()));
+ }
+ {
+ // Invalid 2 decoder pipeline due to wrong type indirect object.
+ CPDF_IndirectObjectHolder objects_holder;
+ auto decoder =
+ pdfium::MakeRetain<CPDF_String>(nullptr, "FlateDecode", false);
+ uint32_t decoder_number =
+ objects_holder.AddIndirectObject(std::move(decoder));
+
+ auto decoders = pdfium::MakeRetain<CPDF_Array>();
+ decoders->AppendNew<CPDF_Reference>(&objects_holder, decoder_number);
+ decoders->AppendNew<CPDF_Name>("LZW");
+ EXPECT_FALSE(ValidateDecoderPipeline(decoders.Get()));
+ }
+ {
+ // Invalid 2 decoder pipeline due to invalid indirect object.
+ CPDF_IndirectObjectHolder objects_holder;
+ auto decoder = pdfium::MakeRetain<CPDF_Name>(nullptr, "DCTDecode");
+ uint32_t decoder_number =
+ objects_holder.AddIndirectObject(std::move(decoder));
+
+ auto decoders = pdfium::MakeRetain<CPDF_Array>();
+ decoders->AppendNew<CPDF_Reference>(&objects_holder, decoder_number);
+ decoders->AppendNew<CPDF_Name>("LZW");
+ EXPECT_FALSE(ValidateDecoderPipeline(decoders.Get()));
+ }
+}
+
// TODO(thestig): Test decoder params.
TEST(ParserDecodeTest, GetDecoderArray) {
{
diff --git a/testing/SUPPRESSIONS b/testing/SUPPRESSIONS
index b224dad..b3409bf 100644
--- a/testing/SUPPRESSIONS
+++ b/testing/SUPPRESSIONS
@@ -361,9 +361,6 @@
# TODO(pdfium:1973): Remove after associated bug is fixed
bug_1973.in * * * *
-# TODO(pdfium:1986): Remove after associated bug is fixed
-bug_1986.in * * * *
-
# TODO(chromium:237527): Remove after associated bug is fixed
bug_237527_1.in * * * *