From a8de9cf541174f80c433b363af6378ebf77a2ca1 Mon Sep 17 00:00:00 2001 From: Matthew Olsson Date: Mon, 21 Mar 2022 11:26:31 -0700 Subject: [PATCH] LibPDF: Keep track of the current object index/generation while Parsing This information is required to decrypt encrypted strings/streams. --- Userland/Libraries/LibPDF/Parser.cpp | 18 +++++++++++++++--- Userland/Libraries/LibPDF/Parser.h | 6 +++++- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibPDF/Parser.cpp b/Userland/Libraries/LibPDF/Parser.cpp index 2a5bbddcf5..89b8109886 100644 --- a/Userland/Libraries/LibPDF/Parser.cpp +++ b/Userland/Libraries/LibPDF/Parser.cpp @@ -613,20 +613,26 @@ PDFErrorOr Parser::parse_possible_indirect_value_or_ref() if (m_reader.matches("obj")) { m_reader.discard(); - return TRY(parse_indirect_value(first_number.get(), second_number.value().get())); + auto index = first_number.get(); + auto generation = second_number.value().get(); + VERIFY(index >= 0); + VERIFY(generation >= 0); + return TRY(parse_indirect_value(index, generation)); } m_reader.load(); return first_number; } -PDFErrorOr> Parser::parse_indirect_value(int index, int generation) +PDFErrorOr> Parser::parse_indirect_value(u32 index, u32 generation) { if (!m_reader.matches("obj")) return error("Expected \"obj\" at beginning of indirect value"); m_reader.move_by(3); if (matches_eol()) consume_eol(); + + push_reference({ index, generation }); auto value = TRY(parse_value()); if (!m_reader.matches("endobj")) return error("Expected \"endobj\" at end of indirect value"); @@ -634,6 +640,8 @@ PDFErrorOr> Parser::parse_indirect_value(int index, consume(6); consume_whitespace(); + pop_reference(); + return make_object(index, generation, value); } @@ -641,7 +649,11 @@ PDFErrorOr> Parser::parse_indirect_value() { auto first_number = TRY(parse_number()); auto second_number = TRY(parse_number()); - return parse_indirect_value(first_number.get(), second_number.get()); + auto index = first_number.get(); + auto generation = second_number.get(); + VERIFY(index >= 0); + VERIFY(generation >= 0); + return parse_indirect_value(index, generation); } PDFErrorOr Parser::parse_number() diff --git a/Userland/Libraries/LibPDF/Parser.h b/Userland/Libraries/LibPDF/Parser.h index db2d49f404..0af0e2041b 100644 --- a/Userland/Libraries/LibPDF/Parser.h +++ b/Userland/Libraries/LibPDF/Parser.h @@ -104,7 +104,7 @@ private: PDFErrorOr parse_value(); PDFErrorOr parse_possible_indirect_value_or_ref(); - PDFErrorOr> parse_indirect_value(int index, int generation); + PDFErrorOr> parse_indirect_value(u32 index, u32 generation); PDFErrorOr> parse_indirect_value(); PDFErrorOr parse_number(); PDFErrorOr> parse_name(); @@ -117,6 +117,9 @@ private: PDFErrorOr> parse_graphics_commands(); + void push_reference(Reference const& ref) { m_current_reference_stack.append(ref); } + void pop_reference() { m_current_reference_stack.take_last(); } + bool matches_eol() const; bool matches_whitespace() const; bool matches_number() const; @@ -142,6 +145,7 @@ private: RefPtr m_xref_table; RefPtr m_trailer; Optional m_linearization_dictionary; + Vector m_current_reference_stack; }; };