Browse Source

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.
Nico Weber 1 year ago
parent
commit
ad5fc0eda1
1 changed files with 18 additions and 16 deletions
  1. 18 16
      Userland/Libraries/LibPDF/Encoding.cpp

+ 18 - 16
Userland/Libraries/LibPDF/Encoding.cpp

@@ -50,22 +50,24 @@ PDFErrorOr<NonnullRefPtr<Encoding>> 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));
-
-    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<NonnullRefPtr<Object>>());
-            VERIFY(!first);
-            auto& object = item.get<NonnullRefPtr<Object>>();
-            auto name = object->cast<NameObject>()->name();
-            encoding->set(current_code_point, name);
-            current_code_point++;
+    if (dict->contains(CommonNames::Differences)) {
+        auto differences_array = TRY(dict->get_array(document, CommonNames::Differences));
+
+        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<NonnullRefPtr<Object>>());
+                VERIFY(!first);
+                auto& object = item.get<NonnullRefPtr<Object>>();
+                auto name = object->cast<NameObject>()->name();
+                encoding->set(current_code_point, name);
+                current_code_point++;
+            }
         }
     }