diff options
author | Matthew Olsson <matthewcolsson@gmail.com> | 2021-05-10 10:36:37 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-18 16:35:23 +0200 |
commit | 03649f85e2788e57c23b9155398809b9683f7691 (patch) | |
tree | 7e2f83dce112dbf2c4ec9bb2241059e018118018 /Userland | |
parent | 2f0a2865f24b94aec389d3d539aaa630e59a9471 (diff) | |
download | serenity-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.cpp | 33 |
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); } |