summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorJulian Offenhäuser <offenhaeuser@protonmail.com>2022-10-27 20:01:56 +0200
committerAndreas Kling <kling@serenityos.org>2022-11-19 15:42:08 +0100
commit16ed407c01b51295b80db5575bf6da75c22294b6 (patch)
treef1b4e5e21a2e15779189b63dbc7a14942edb5369 /Userland/Libraries
parentbecd648a781848b5570b134169fb77c4dee5c47b (diff)
downloadserenity-16ed407c01b51295b80db5575bf6da75c22294b6.zip
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.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibPDF/Parser.cpp19
1 files 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<NonnullRefPtr<StreamObject>> Parser::parse_stream(NonnullRefPtr<DictO
m_document->security_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<FlyString> 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<ArrayObject>()) {
+ auto filter_array = filter_object->cast<ArrayObject>();
+ 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<NameObject>()->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;