From 58ff7b533685efdae3639ec4837e357d5110f133 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 22 Oct 2023 22:57:27 -0400 Subject: [PATCH] LibPDF: Support offset size 3 in CFF index reading ...and replace template instantiations with a loop, to make this easily possible. Vaguely nice for code size as well. Needed for example in 0000054.pdf and 0000354.pdf in 0000.zip in the pdfa dataset. --- Userland/Libraries/LibPDF/Fonts/CFF.cpp | 37 +++++++++++++------------ Userland/Libraries/LibPDF/Fonts/CFF.h | 3 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.cpp b/Userland/Libraries/LibPDF/Fonts/CFF.cpp index 26298be5b53..46c86f42689 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.cpp +++ b/Userland/Libraries/LibPDF/Fonts/CFF.cpp @@ -874,26 +874,31 @@ PDFErrorOr CFF::parse_index(Reader& reader, IndexDataHandler&& data_handle if (count == 0) return {}; auto offset_size = TRY(reader.try_read()); - if (offset_size == 1) - return parse_index_data(count, reader, data_handler); - if (offset_size == 2) - return parse_index_data(count, reader, data_handler); - if (offset_size == 4) - return parse_index_data(count, reader, data_handler); - VERIFY_NOT_REACHED(); + if (offset_size > 4) + return error("CFF INDEX Data offset_size > 4 not supported"); + return parse_index_data(offset_size, count, reader, data_handler); } -template -PDFErrorOr CFF::parse_index_data(Card16 count, Reader& reader, IndexDataHandler& handler) +PDFErrorOr CFF::parse_index_data(OffSize offset_size, Card16 count, Reader& reader, IndexDataHandler& handler) { // CFF spec, "5 INDEX Data" - OffsetType last_data_end = 1; - auto offset_refpoint = reader.offset() + sizeof(OffsetType) * (count + 1) - 1; + u32 last_data_end = 1; + + auto read_offset = [&]() -> PDFErrorOr { + u32 offset = 0; + for (OffSize i = 0; i < offset_size; ++i) + offset = (offset << 8) | TRY(reader.try_read()); + return offset; + }; + + auto offset_refpoint = reader.offset() + offset_size * (count + 1) - 1; for (u16 i = 0; i < count; i++) { reader.save(); - reader.move_by(sizeof(OffsetType) * i); - OffsetType data_start = reader.read>(); - last_data_end = reader.read>(); + + reader.move_by(offset_size * i); + u32 data_start = TRY(read_offset()); + last_data_end = TRY(read_offset()); + auto data_size = last_data_end - data_start; reader.move_to(offset_refpoint + data_start); TRY(handler(reader.bytes().slice(reader.offset(), data_size))); @@ -903,10 +908,6 @@ PDFErrorOr CFF::parse_index_data(Card16 count, Reader& reader, IndexDataHa return {}; } -template PDFErrorOr CFF::parse_index_data(Card16, Reader&, IndexDataHandler&); -template PDFErrorOr CFF::parse_index_data(Card16, Reader&, IndexDataHandler&); -template PDFErrorOr CFF::parse_index_data(Card16, Reader&, IndexDataHandler&); - int CFF::load_int_dict_operand(u8 b0, Reader& reader) { // CFF spec, "Table 3 Operand Encoding" diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.h b/Userland/Libraries/LibPDF/Fonts/CFF.h index 49b705163ea..50ff7fb4eb2 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.h +++ b/Userland/Libraries/LibPDF/Fonts/CFF.h @@ -81,8 +81,7 @@ public: using IndexDataHandler = Function(ReadonlyBytes const&)>; static PDFErrorOr parse_index(Reader& reader, IndexDataHandler&&); - template - static PDFErrorOr parse_index_data(Card16 count, Reader& reader, IndexDataHandler&); + static PDFErrorOr parse_index_data(OffSize offset_size, Card16 count, Reader& reader, IndexDataHandler&); template using DictEntryHandler = Function(OperatorT, Vector const&)>;