From 16ed407c01b51295b80db5575bf6da75c22294b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julian=20Offenh=C3=A4user?= Date: Thu, 27 Oct 2022 20:01:56 +0200 Subject: [PATCH] LibPDF: Support cascading stream filters You can specify multiple filters as an array, where each one is fed the output of the one before it. --- Userland/Libraries/LibPDF/Parser.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/Userland/Libraries/LibPDF/Parser.cpp b/Userland/Libraries/LibPDF/Parser.cpp index 61d1f51bef..5c3095efc6 100644 --- a/Userland/Libraries/LibPDF/Parser.cpp +++ b/Userland/Libraries/LibPDF/Parser.cpp @@ -476,13 +476,20 @@ PDFErrorOr> Parser::parse_stream(NonnullRefPtrsecurity_handler()->decrypt(stream_object, m_current_reference_stack.last()); if (dict->contains(CommonNames::Filter)) { - auto filter_type = MUST(dict->get_name(m_document, CommonNames::Filter))->name(); - auto maybe_bytes = Filter::decode(stream_object->bytes(), filter_type); - if (maybe_bytes.is_error()) { - warnln("Failed to decode filter: {}", maybe_bytes.error().string_literal()); - return error(String::formatted("Failed to decode filter {}", maybe_bytes.error().string_literal())); + Vector filters; + + // We may either get a single filter or an array of cascading filters + auto filter_object = TRY(dict->get_object(m_document, CommonNames::Filter)); + if (filter_object->is()) { + auto filter_array = filter_object->cast(); + for (size_t i = 0; i < filter_array->size(); ++i) + filters.append(TRY(filter_array->get_name_at(m_document, i))->name()); + } else { + filters.append(filter_object->cast()->name()); } - stream_object->buffer() = maybe_bytes.release_value(); + + for (auto const& filter_type : filters) + stream_object->buffer() = TRY(Filter::decode(stream_object->bytes(), filter_type)); } return stream_object;