summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorMatthew Olsson <matthewcolsson@gmail.com>2021-05-10 10:36:37 -0700
committerAndreas Kling <kling@serenityos.org>2021-05-18 16:35:23 +0200
commit03649f85e2788e57c23b9155398809b9683f7691 (patch)
tree7e2f83dce112dbf2c4ec9bb2241059e018118018 /Userland
parent2f0a2865f24b94aec389d3d539aaa630e59a9471 (diff)
downloadserenity-03649f85e2788e57c23b9155398809b9683f7691.zip
LibPDF: Don't rely on a stream's /Length key existing
Some PDFs omit this key apparently, but Firefox opens them fine. Let's emulate that behavior.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibPDF/Parser.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/Userland/Libraries/LibPDF/Parser.cpp b/Userland/Libraries/LibPDF/Parser.cpp
index 2e7d5ab57e..2c3d5b3b8b 100644
--- a/Userland/Libraries/LibPDF/Parser.cpp
+++ b/Userland/Libraries/LibPDF/Parser.cpp
@@ -617,12 +617,35 @@ NonnullRefPtr<StreamObject> Parser::parse_stream(NonnullRefPtr<DictObject> dict)
m_reader.move_by(6);
consume_eol();
- auto length_value = dict->map().get("Length");
- VERIFY(length_value.has_value());
- auto length = length_value.value();
- VERIFY(length.is_int());
+ ReadonlyBytes bytes;
- auto bytes = m_reader.bytes().slice(m_reader.offset(), length.as_int());
+ auto maybe_length = dict->get("Length");
+ if (maybe_length.has_value()) {
+ // The PDF writer has kindly provided us with the direct length of the stream
+ m_reader.save();
+ auto length = m_document->resolve_to<int>(maybe_length.value());
+ m_reader.load();
+ bytes = m_reader.bytes().slice(m_reader.offset(), length);
+ m_reader.move_by(length);
+ consume_whitespace();
+ } else {
+ // We have to look for the endstream keyword
+ auto stream_start = m_reader.offset();
+
+ while (true) {
+ m_reader.move_until([&] { return matches_eol(); });
+ auto potential_stream_end = m_reader.offset();
+ consume_eol();
+ if (!m_reader.matches("endstream"))
+ continue;
+
+ bytes = m_reader.bytes().slice(stream_start, potential_stream_end - stream_start);
+ break;
+ }
+ }
+
+ m_reader.move_by(9);
+ consume_whitespace();
return make_object<StreamObject>(dict, bytes);
}