From ad5fc0eda118ce843f52354652f1aaf9fa968963 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Wed, 3 Jan 2024 19:43:06 -0500 Subject: [PATCH] LibPDF: An Encoding's /Differences entry is optional Per "TABLE 5.11 Entries in an encoding dictionary", /Differences is optional. (Per "Encodings for TrueType Fonts" in 5.5.5 Character Encoding, nonsymbolic truetype fonts are even recommended to have "no Differences array." But in practice, most seem to have it.) Fixes crashes on: * 0000001.pdf * 0000574.pdf * 0000337.pdf All three don't render super great, but at least they no longer crash. --- Userland/Libraries/LibPDF/Encoding.cpp | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Userland/Libraries/LibPDF/Encoding.cpp b/Userland/Libraries/LibPDF/Encoding.cpp index 95f7b364ef..0ce2da76c8 100644 --- a/Userland/Libraries/LibPDF/Encoding.cpp +++ b/Userland/Libraries/LibPDF/Encoding.cpp @@ -50,22 +50,24 @@ PDFErrorOr> Encoding::from_object(Document* document, No encoding->m_descriptors = TRY(base_encoding->m_descriptors.clone()); encoding->m_name_mapping = TRY(base_encoding->m_name_mapping.clone()); - auto differences_array = TRY(dict->get_array(document, CommonNames::Differences)); + if (dict->contains(CommonNames::Differences)) { + auto differences_array = TRY(dict->get_array(document, CommonNames::Differences)); - u16 current_code_point = 0; - bool first = true; + u16 current_code_point = 0; + bool first = true; - for (auto& item : *differences_array) { - if (item.has_u32()) { - current_code_point = item.to_int(); - first = false; - } else { - VERIFY(item.has>()); - VERIFY(!first); - auto& object = item.get>(); - auto name = object->cast()->name(); - encoding->set(current_code_point, name); - current_code_point++; + for (auto& item : *differences_array) { + if (item.has_u32()) { + current_code_point = item.to_int(); + first = false; + } else { + VERIFY(item.has>()); + VERIFY(!first); + auto& object = item.get>(); + auto name = object->cast()->name(); + encoding->set(current_code_point, name); + current_code_point++; + } } }