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 * * * *