From 03649f85e2788e57c23b9155398809b9683f7691 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Mon, 10 May 2021 10:36:37 -0700 Subject: [PATCH] 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. --- Userland/Libraries/LibPDF/Parser.cpp | 33 +++++++++++++++++++++++----- 1 file 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 Parser::parse_stream(NonnullRefPtr 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(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(dict, bytes); }