From b7b60762947605f008b2d96a2471518a24efbb49 Mon Sep 17 00:00:00 2001
From: Jonas Jenwald <jonas.jenwald@gmail.com>
Date: Wed, 1 Sep 2021 12:22:49 +0200
Subject: [PATCH] Always prefer the post-table for TrueType fonts with (0, x)
 cmap-tables (issue 13433)

While I don't know if this is necessarily the "correct" solution, it does fix issue 13433 without breaking any of the existing reference-tests.
---
 src/core/fonts.js             | 13 ++++++++-----
 test/pdfs/issue13433.pdf.link |  1 +
 test/test_manifest.json       |  8 ++++++++
 3 files changed, 17 insertions(+), 5 deletions(-)
 create mode 100644 test/pdfs/issue13433.pdf.link

diff --git a/src/core/fonts.js b/src/core/fonts.js
index 87e6f7758..ca2c01179 100644
--- a/src/core/fonts.js
+++ b/src/core/fonts.js
@@ -2606,7 +2606,8 @@ class Font {
       const cmapEncodingId = cmapTable.encodingId;
       const cmapMappings = cmapTable.mappings;
       const cmapMappingsLength = cmapMappings.length;
-      let baseEncoding = [];
+      let baseEncoding = [],
+        forcePostTable = false;
       if (
         properties.hasEncoding &&
         (properties.baseEncodingName === "MacRomanEncoding" ||
@@ -2615,9 +2616,8 @@ class Font {
         baseEncoding = getEncoding(properties.baseEncodingName);
       }
 
-      // If the font has an encoding and is not symbolic then follow the
-      // rules in section 9.6.6.4 of the spec on how to map 3,1 and 1,0
-      // cmaps.
+      // If the font has an encoding and is not symbolic then follow the rules
+      // in section 9.6.6.4 of the spec on how to map 3,1 and 1,0 cmaps.
       if (
         properties.hasEncoding &&
         !this.isSymbolicFont &&
@@ -2664,6 +2664,9 @@ class Font {
         for (let i = 0; i < cmapMappingsLength; ++i) {
           charCodeToGlyphId[cmapMappings[i].charCode] = cmapMappings[i].glyphId;
         }
+        // Always prefer the BaseEncoding/Differences arrays, when they exist
+        // (fixes issue13433.pdf).
+        forcePostTable = true;
       } else {
         // When there is only a (1, 0) cmap table, the char code is a single
         // byte and it is used directly as the char code.
@@ -2695,7 +2698,7 @@ class Font {
         (baseEncoding.length || this.differences.length)
       ) {
         for (let i = 0; i < 256; ++i) {
-          if (charCodeToGlyphId[i] !== undefined) {
+          if (!forcePostTable && charCodeToGlyphId[i] !== undefined) {
             continue;
           }
           const glyphName = this.differences[i] || baseEncoding[i];
diff --git a/test/pdfs/issue13433.pdf.link b/test/pdfs/issue13433.pdf.link
new file mode 100644
index 000000000..0062c6756
--- /dev/null
+++ b/test/pdfs/issue13433.pdf.link
@@ -0,0 +1 @@
+https://github.com/mozilla/pdf.js/files/6537699/pos36.pdf
diff --git a/test/test_manifest.json b/test/test_manifest.json
index 39e28e26d..b1f1814a7 100644
--- a/test/test_manifest.json
+++ b/test/test_manifest.json
@@ -1294,6 +1294,14 @@
        "enableXfa": true,
        "type": "eq"
     },
+    {  "id": "issue13433",
+       "file": "pdfs/issue13433.pdf",
+       "md5": "4038cd87ff48fd54b3c4a36593d2ba03",
+       "link": true,
+       "rounds": 1,
+       "lastPage": 1,
+       "type": "eq"
+    },
     {  "id": "xfa_issue13668",
        "file": "pdfs/xfa_issue13668.pdf",
        "md5": "8a5ed3c8a58b425b1ec53329334a0f5b",