fofi/FoFiType1C.cc |  435 ++++++++++++++++++++++++++---------------------------
 1 file changed, 220 insertions(+), 215 deletions(-)

New commits:
commit a5e5649ecf16fa05770620dbbd4985935dc2bbff
Author: Albert Astals Cid <[email protected]>
Date:   Mon Sep 11 12:35:16 2017 +0200

    Fix crash in FoFiType1C::convertToType0 in broken files
    
    Bug #102653

diff --git a/fofi/FoFiType1C.cc b/fofi/FoFiType1C.cc
index c4595a32..7a827855 100644
--- a/fofi/FoFiType1C.cc
+++ b/fofi/FoFiType1C.cc
@@ -13,7 +13,7 @@
 // All changes made under the Poppler project to this file are licensed
 // under GPL version 2 or later
 //
-// Copyright (C) 2009, 2010 Albert Astals Cid <[email protected]>
+// Copyright (C) 2009, 2010, 2017 Albert Astals Cid <[email protected]>
 // Copyright (C) 2012 Thomas Freitag <[email protected]>
 //
 // To see a description of the changes please see the Changelog file that
@@ -33,6 +33,7 @@
 #include "goo/gmem.h"
 #include "goo/gstrtod.h"
 #include "goo/GooString.h"
+#include "poppler/Error.h"
 #include "FoFiEncodings.h"
 #include "FoFiType1C.h"
 
@@ -879,253 +880,257 @@ void FoFiType1C::convertToType0(char *psName, int 
*codeMap, int nCodes,
     }
   }
 
+  if (privateDicts) {
   // write the descendant Type 1 fonts
-  for (i = 0; i < nCIDs; i += 256) {
-
-    //~ this assumes that all CIDs in this block have the same FD --
-    //~ to handle multiple FDs correctly, need to somehow divide the
-    //~ font up by FD; as a kludge we ignore CID 0, which is .notdef
-    fd = 0;
-    // if fdSelect is NULL, we have an 8-bit font, so just leave fd=0
-    if (fdSelect) {
-      for (j = i==0 ? 1 : 0; j < 256 && i+j < nCIDs; ++j) {
-        if (cidMap[i+j] >= 0) {
-          fd = fdSelect[cidMap[i+j]];
-          break;
-        }
+    for (i = 0; i < nCIDs; i += 256) {
+
+      //~ this assumes that all CIDs in this block have the same FD --
+      //~ to handle multiple FDs correctly, need to somehow divide the
+      //~ font up by FD; as a kludge we ignore CID 0, which is .notdef
+      fd = 0;
+      // if fdSelect is NULL, we have an 8-bit font, so just leave fd=0
+      if (fdSelect) {
+       for (j = i==0 ? 1 : 0; j < 256 && i+j < nCIDs; ++j) {
+         if (cidMap[i+j] >= 0) {
+           fd = fdSelect[cidMap[i+j]];
+           break;
+         }
+       }
       }
-    }
 
-    // font dictionary (unencrypted section)
-    (*outputFunc)(outputStream, "16 dict begin\n", 14);
-    (*outputFunc)(outputStream, "/FontName /", 11);
-    (*outputFunc)(outputStream, psName, strlen(psName));
-    buf = GooString::format("_{0:02x} def\n", i >> 8);
-    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
-    delete buf;
-    (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
-    if (privateDicts[fd].hasFontMatrix) {
-      buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} 
{4:.8g} {5:.8g}] def\n",
-                           privateDicts[fd].fontMatrix[0],
-                           privateDicts[fd].fontMatrix[1],
-                           privateDicts[fd].fontMatrix[2],
-                           privateDicts[fd].fontMatrix[3],
-                           privateDicts[fd].fontMatrix[4],
-                           privateDicts[fd].fontMatrix[5]);
+      // font dictionary (unencrypted section)
+      (*outputFunc)(outputStream, "16 dict begin\n", 14);
+      (*outputFunc)(outputStream, "/FontName /", 11);
+      (*outputFunc)(outputStream, psName, strlen(psName));
+      buf = GooString::format("_{0:02x} def\n", i >> 8);
       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
       delete buf;
-    } else if (topDict.hasFontMatrix) {
-      (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
-    } else {
-      (*outputFunc)(outputStream,
-                   "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
-    }
-    buf = GooString::format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] 
def\n",
-                         topDict.fontBBox[0], topDict.fontBBox[1],
-                         topDict.fontBBox[2], topDict.fontBBox[3]);
-    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
-    delete buf;
-    buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
-    (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
-    delete buf;
-    if (topDict.paintType != 0) {
-      buf = GooString::format("/StrokeWidth {0:.4g} def\n", 
topDict.strokeWidth);
-      (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
-      delete buf;
-    }
-    (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
-    for (j = 0; j < 256 && i+j < nCIDs; ++j) {
-      buf = GooString::format("dup {0:d} /c{1:02x} put\n", j, j);
+      (*outputFunc)(outputStream, "/FontType 1 def\n", 16);
+      if (privateDicts[fd].hasFontMatrix) {
+       buf = GooString::format("/FontMatrix [{0:.8g} {1:.8g} {2:.8g} {3:.8g} 
{4:.8g} {5:.8g}] def\n",
+                             privateDicts[fd].fontMatrix[0],
+                             privateDicts[fd].fontMatrix[1],
+                             privateDicts[fd].fontMatrix[2],
+                             privateDicts[fd].fontMatrix[3],
+                             privateDicts[fd].fontMatrix[4],
+                             privateDicts[fd].fontMatrix[5]);
+       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
+       delete buf;
+      } else if (topDict.hasFontMatrix) {
+       (*outputFunc)(outputStream, "/FontMatrix [1 0 0 1 0 0] def\n", 30);
+      } else {
+       (*outputFunc)(outputStream,
+                     "/FontMatrix [0.001 0 0 0.001 0 0] def\n", 38);
+      }
+      buf = GooString::format("/FontBBox [{0:.4g} {1:.4g} {2:.4g} {3:.4g}] 
def\n",
+                           topDict.fontBBox[0], topDict.fontBBox[1],
+                           topDict.fontBBox[2], topDict.fontBBox[3]);
       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
       delete buf;
-    }
-    if (j < 256) {
-      buf = GooString::format("{0:d} 1 255 {{ 1 index exch /.notdef put }} 
for\n",
-                           j);
+      buf = GooString::format("/PaintType {0:d} def\n", topDict.paintType);
       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
       delete buf;
-    }
-    (*outputFunc)(outputStream, "readonly def\n", 13);
-    (*outputFunc)(outputStream, "currentdict end\n", 16);
-
-    // start the binary section
-    (*outputFunc)(outputStream, "currentfile eexec\n", 18);
-    eb.outputFunc = outputFunc;
-    eb.outputStream = outputStream;
-    eb.ascii = gTrue;
-    eb.r1 = 55665;
-    eb.line = 0;
-
-    // start the private dictionary
-    eexecWrite(&eb, "\x83\xca\x73\xd5");
-    eexecWrite(&eb, "dup /Private 32 dict dup begin\n");
-    eexecWrite(&eb, "/RD {string currentfile exch readstring pop}"
-              " executeonly def\n");
-    eexecWrite(&eb, "/ND {noaccess def} executeonly def\n");
-    eexecWrite(&eb, "/NP {noaccess put} executeonly def\n");
-    eexecWrite(&eb, "/MinFeature {16 16} def\n");
-    eexecWrite(&eb, "/password 5839 def\n");
-    if (privateDicts[fd].nBlueValues) {
-      eexecWrite(&eb, "/BlueValues [");
-      for (k = 0; k < privateDicts[fd].nBlueValues; ++k) {
-       buf = GooString::format("{0:s}{1:d}",
-                             k > 0 ? " " : "",
-                             privateDicts[fd].blueValues[k]);
+      if (topDict.paintType != 0) {
+       buf = GooString::format("/StrokeWidth {0:.4g} def\n", 
topDict.strokeWidth);
+       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
+       delete buf;
+      }
+      (*outputFunc)(outputStream, "/Encoding 256 array\n", 20);
+      for (j = 0; j < 256 && i+j < nCIDs; ++j) {
+       buf = GooString::format("dup {0:d} /c{1:02x} put\n", j, j);
+       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
+       delete buf;
+      }
+      if (j < 256) {
+       buf = GooString::format("{0:d} 1 255 {{ 1 index exch /.notdef put }} 
for\n",
+                             j);
+       (*outputFunc)(outputStream, buf->getCString(), buf->getLength());
+       delete buf;
+      }
+      (*outputFunc)(outputStream, "readonly def\n", 13);
+      (*outputFunc)(outputStream, "currentdict end\n", 16);
+
+      // start the binary section
+      (*outputFunc)(outputStream, "currentfile eexec\n", 18);
+      eb.outputFunc = outputFunc;
+      eb.outputStream = outputStream;
+      eb.ascii = gTrue;
+      eb.r1 = 55665;
+      eb.line = 0;
+
+      // start the private dictionary
+      eexecWrite(&eb, "\x83\xca\x73\xd5");
+      eexecWrite(&eb, "dup /Private 32 dict dup begin\n");
+      eexecWrite(&eb, "/RD {string currentfile exch readstring pop}"
+               " executeonly def\n");
+      eexecWrite(&eb, "/ND {noaccess def} executeonly def\n");
+      eexecWrite(&eb, "/NP {noaccess put} executeonly def\n");
+      eexecWrite(&eb, "/MinFeature {16 16} def\n");
+      eexecWrite(&eb, "/password 5839 def\n");
+      if (privateDicts[fd].nBlueValues) {
+       eexecWrite(&eb, "/BlueValues [");
+       for (k = 0; k < privateDicts[fd].nBlueValues; ++k) {
+         buf = GooString::format("{0:s}{1:d}",
+                               k > 0 ? " " : "",
+                               privateDicts[fd].blueValues[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].nOtherBlues) {
+       eexecWrite(&eb, "/OtherBlues [");
+       for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) {
+         buf = GooString::format("{0:s}{1:d}",
+                               k > 0 ? " " : "",
+                               privateDicts[fd].otherBlues[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].nFamilyBlues) {
+       eexecWrite(&eb, "/FamilyBlues [");
+       for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) {
+         buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
+                               privateDicts[fd].familyBlues[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].nFamilyOtherBlues) {
+       eexecWrite(&eb, "/FamilyOtherBlues [");
+       for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) {
+         buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
+                               privateDicts[fd].familyOtherBlues[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].blueScale != 0.039625) {
+       buf = GooString::format("/BlueScale {0:.4g} def\n",
+                             privateDicts[fd].blueScale);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].nOtherBlues) {
-      eexecWrite(&eb, "/OtherBlues [");
-      for (k = 0; k < privateDicts[fd].nOtherBlues; ++k) {
-       buf = GooString::format("{0:s}{1:d}",
-                             k > 0 ? " " : "",
-                             privateDicts[fd].otherBlues[k]);
+      if (privateDicts[fd].blueShift != 7) {
+       buf = GooString::format("/BlueShift {0:d} def\n",
+                             privateDicts[fd].blueShift);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].nFamilyBlues) {
-      eexecWrite(&eb, "/FamilyBlues [");
-      for (k = 0; k < privateDicts[fd].nFamilyBlues; ++k) {
-       buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
-                             privateDicts[fd].familyBlues[k]);
+      if (privateDicts[fd].blueFuzz != 1) {
+       buf = GooString::format("/BlueFuzz {0:d} def\n",
+                             privateDicts[fd].blueFuzz);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].nFamilyOtherBlues) {
-      eexecWrite(&eb, "/FamilyOtherBlues [");
-      for (k = 0; k < privateDicts[fd].nFamilyOtherBlues; ++k) {
-       buf = GooString::format("{0:s}{1:d}", k > 0 ? " " : "",
-                             privateDicts[fd].familyOtherBlues[k]);
+      if (privateDicts[fd].hasStdHW) {
+       buf = GooString::format("/StdHW [{0:.4g}] def\n", 
privateDicts[fd].stdHW);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].blueScale != 0.039625) {
-      buf = GooString::format("/BlueScale {0:.4g} def\n",
-                           privateDicts[fd].blueScale);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].blueShift != 7) {
-      buf = GooString::format("/BlueShift {0:d} def\n",
-                           privateDicts[fd].blueShift);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].blueFuzz != 1) {
-      buf = GooString::format("/BlueFuzz {0:d} def\n",
-                           privateDicts[fd].blueFuzz);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].hasStdHW) {
-      buf = GooString::format("/StdHW [{0:.4g}] def\n", 
privateDicts[fd].stdHW);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].hasStdVW) {
-      buf = GooString::format("/StdVW [{0:.4g}] def\n", 
privateDicts[fd].stdVW);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].nStemSnapH) {
-      eexecWrite(&eb, "/StemSnapH [");
-      for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
-       buf = GooString::format("{0:s}{1:.4g}",
-                             k > 0 ? " " : "", privateDicts[fd].stemSnapH[k]);
+      if (privateDicts[fd].hasStdVW) {
+       buf = GooString::format("/StdVW [{0:.4g}] def\n", 
privateDicts[fd].stdVW);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].nStemSnapV) {
-      eexecWrite(&eb, "/StemSnapV [");
-      for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
-       buf = GooString::format("{0:s}{1:.4g}",
-                             k > 0 ? " " : "", privateDicts[fd].stemSnapV[k]);
+      if (privateDicts[fd].nStemSnapH) {
+       eexecWrite(&eb, "/StemSnapH [");
+       for (k = 0; k < privateDicts[fd].nStemSnapH; ++k) {
+         buf = GooString::format("{0:s}{1:.4g}",
+                               k > 0 ? " " : "", 
privateDicts[fd].stemSnapH[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].nStemSnapV) {
+       eexecWrite(&eb, "/StemSnapV [");
+       for (k = 0; k < privateDicts[fd].nStemSnapV; ++k) {
+         buf = GooString::format("{0:s}{1:.4g}",
+                               k > 0 ? " " : "", 
privateDicts[fd].stemSnapV[k]);
+         eexecWrite(&eb, buf->getCString());
+         delete buf;
+       }
+       eexecWrite(&eb, "] def\n");
+      }
+      if (privateDicts[fd].hasForceBold) {
+       buf = GooString::format("/ForceBold {0:s} def\n",
+                             privateDicts[fd].forceBold ? "true" : "false");
+       eexecWrite(&eb, buf->getCString());
+       delete buf;
+      }
+      if (privateDicts[fd].forceBoldThreshold != 0) {
+       buf = GooString::format("/ForceBoldThreshold {0:.4g} def\n",
+                             privateDicts[fd].forceBoldThreshold);
+       eexecWrite(&eb, buf->getCString());
+       delete buf;
+      }
+      if (privateDicts[fd].languageGroup != 0) {
+       buf = GooString::format("/LanguageGroup {0:d} def\n",
+                             privateDicts[fd].languageGroup);
+       eexecWrite(&eb, buf->getCString());
+       delete buf;
+      }
+      if (privateDicts[fd].expansionFactor != 0.06) {
+       buf = GooString::format("/ExpansionFactor {0:.4g} def\n",
+                             privateDicts[fd].expansionFactor);
        eexecWrite(&eb, buf->getCString());
        delete buf;
       }
-      eexecWrite(&eb, "] def\n");
-    }
-    if (privateDicts[fd].hasForceBold) {
-      buf = GooString::format("/ForceBold {0:s} def\n",
-                           privateDicts[fd].forceBold ? "true" : "false");
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].forceBoldThreshold != 0) {
-      buf = GooString::format("/ForceBoldThreshold {0:.4g} def\n",
-                           privateDicts[fd].forceBoldThreshold);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].languageGroup != 0) {
-      buf = GooString::format("/LanguageGroup {0:d} def\n",
-                           privateDicts[fd].languageGroup);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
-    if (privateDicts[fd].expansionFactor != 0.06) {
-      buf = GooString::format("/ExpansionFactor {0:.4g} def\n",
-                           privateDicts[fd].expansionFactor);
-      eexecWrite(&eb, buf->getCString());
-      delete buf;
-    }
 
-    // set up the subroutines
-    ok = gTrue;
-    getIndex(privateDicts[fd].subrsOffset, &subrIdx, &ok);
-    if (!ok) {
-      subrIdx.pos = -1;
-    }
+      // set up the subroutines
+      ok = gTrue;
+      getIndex(privateDicts[fd].subrsOffset, &subrIdx, &ok);
+      if (!ok) {
+       subrIdx.pos = -1;
+      }
 
-    // start the CharStrings
-    eexecWrite(&eb, "2 index /CharStrings 256 dict dup begin\n");
+      // start the CharStrings
+      eexecWrite(&eb, "2 index /CharStrings 256 dict dup begin\n");
 
-    // write the .notdef CharString
-    ok = gTrue;
-    getIndexVal(&charStringsIdx, 0, &val, &ok);
-    if (ok) {
-      eexecCvtGlyph(&eb, ".notdef", val.pos, val.len,
-                   &subrIdx, &privateDicts[fd]);
-    }
-
-    // write the CharStrings
-    for (j = 0; j < 256 && i+j < nCIDs; ++j) {
-      if (cidMap[i+j] >= 0) {
-       ok = gTrue;
-       getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok);
-       if (ok) {
-         buf = GooString::format("c{0:02x}", j);
-         eexecCvtGlyph(&eb, buf->getCString(), val.pos, val.len,
-                       &subrIdx, &privateDicts[fd]);
-         delete buf;
-       }
+      // write the .notdef CharString
+      ok = gTrue;
+      getIndexVal(&charStringsIdx, 0, &val, &ok);
+      if (ok) {
+       eexecCvtGlyph(&eb, ".notdef", val.pos, val.len,
+                     &subrIdx, &privateDicts[fd]);
       }
-    }
-    eexecWrite(&eb, "end\n");
-    eexecWrite(&eb, "end\n");
-    eexecWrite(&eb, "readonly put\n");
-    eexecWrite(&eb, "noaccess put\n");
-    eexecWrite(&eb, "dup /FontName get exch definefont pop\n");
-    eexecWrite(&eb, "mark currentfile closefile\n");
 
-    // trailer
-    if (eb.line > 0) {
-      (*outputFunc)(outputStream, "\n", 1);
-    }
-    for (j = 0; j < 8; ++j) {
-      (*outputFunc)(outputStream, 
"0000000000000000000000000000000000000000000000000000000000000000\n", 65);
+      // write the CharStrings
+      for (j = 0; j < 256 && i+j < nCIDs; ++j) {
+       if (cidMap[i+j] >= 0) {
+         ok = gTrue;
+         getIndexVal(&charStringsIdx, cidMap[i+j], &val, &ok);
+         if (ok) {
+           buf = GooString::format("c{0:02x}", j);
+           eexecCvtGlyph(&eb, buf->getCString(), val.pos, val.len,
+                         &subrIdx, &privateDicts[fd]);
+           delete buf;
+         }
+       }
+      }
+      eexecWrite(&eb, "end\n");
+      eexecWrite(&eb, "end\n");
+      eexecWrite(&eb, "readonly put\n");
+      eexecWrite(&eb, "noaccess put\n");
+      eexecWrite(&eb, "dup /FontName get exch definefont pop\n");
+      eexecWrite(&eb, "mark currentfile closefile\n");
+
+      // trailer
+      if (eb.line > 0) {
+       (*outputFunc)(outputStream, "\n", 1);
+      }
+      for (j = 0; j < 8; ++j) {
+       (*outputFunc)(outputStream, 
"0000000000000000000000000000000000000000000000000000000000000000\n", 65);
+      }
+      (*outputFunc)(outputStream, "cleartomark\n", 12);
     }
-    (*outputFunc)(outputStream, "cleartomark\n", 12);
+  } else {
+    error(errSyntaxError, -1, "FoFiType1C::convertToType0 without 
privateDicts");
   }
 
   // write the Type 0 parent font
_______________________________________________
poppler mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to