[poppler] poppler/FontInfo.cc poppler/FontInfo.h

Albert Astals Cid aacid at kemper.freedesktop.org
Tue Jul 22 12:09:01 PDT 2008


 poppler/FontInfo.cc |   44 ++++++++++++++++++++++++++++++++++++--------
 poppler/FontInfo.h  |    4 ++++
 2 files changed, 40 insertions(+), 8 deletions(-)

New commits:
commit 8dc7afaeea08183de331ecfd41ce1971e7772fd0
Author: Albert Astals Cid <aacid at kde.org>
Date:   Tue Jul 22 21:05:03 2008 +0200

    Some documents have loops in XObject dictionaries, make sure we don't get in an infinite loop while traversing them
    
    Fixes infinite loop on http://bugs.kde.org/show_bug.cgi?id=166145

diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
index d98f1c6..fa011d8 100644
--- a/poppler/FontInfo.cc
+++ b/poppler/FontInfo.cc
@@ -18,10 +18,13 @@ FontInfoScanner::FontInfoScanner(PDFDoc *docA) {
   currentPage = 1;
   fonts = NULL;
   fontsLen = fontsSize = 0;
+  visitedXObjects = NULL;
+  visitedXObjectsLen = visitedXObjectsSize = 0;
 }
 
 FontInfoScanner::~FontInfoScanner() {
   gfree(fonts);
+  gfree(visitedXObjects);
 }
 
 GooList *FontInfoScanner::scan(int nPages) {
@@ -69,7 +72,7 @@ GooList *FontInfoScanner::scan(int nPages) {
 }
 
 void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
-  Object obj1, obj2, xObjDict, xObj, resObj;
+  Object obj1, obj2, xObjDict, xObj, xObj2, resObj;
   Ref r;
   GfxFontDict *gfxFontDict;
   GfxFont *font;
@@ -122,15 +125,40 @@ void FontInfoScanner::scanFonts(Dict *resDict, GooList *fontsList) {
   resDict->lookup("XObject", &xObjDict);
   if (xObjDict.isDict()) {
     for (i = 0; i < xObjDict.dictGetLength(); ++i) {
-      xObjDict.dictGetVal(i, &xObj);
-      if (xObj.isStream()) {
-	xObj.streamGetDict()->lookup("Resources", &resObj);
-	if (resObj.isDict() && resObj.getDict() != resDict) {
-	  scanFonts(resObj.getDict(), fontsList);
-	}
-	resObj.free();
+      xObjDict.dictGetValNF(i, &xObj);
+      if (xObj.isRef()) {
+        GBool alreadySeen = gFalse;
+        // check for an already-seen XObject
+        for (int k = 0; k < visitedXObjectsLen; ++k) {
+          if (xObj.getRef().num == visitedXObjects[k].num &&
+              xObj.getRef().gen == visitedXObjects[k].gen) {
+            alreadySeen = gTrue;
+          }
+        }
+
+        if (alreadySeen) {
+          xObj.free();
+          continue;
+        }
+
+        if (visitedXObjectsLen == visitedXObjectsSize) {
+          visitedXObjectsSize += 32;
+          visitedXObjects = (Ref *)grealloc(visitedXObjects, visitedXObjectsSize * sizeof(Ref));
+        }
+        visitedXObjects[visitedXObjectsLen++] = xObj.getRef();
+      }
+
+      xObj.fetch(doc->getXRef(), &xObj2);
+
+      if (xObj2.isStream()) {
+        xObj2.streamGetDict()->lookup("Resources", &resObj);
+        if (resObj.isDict() && resObj.getDict() != resDict) {
+          scanFonts(resObj.getDict(), fontsList);
+        }
+        resObj.free();
       }
       xObj.free();
+      xObj2.free();
     }
   }
   xObjDict.free();
diff --git a/poppler/FontInfo.h b/poppler/FontInfo.h
index 1862845..aec51bb 100644
--- a/poppler/FontInfo.h
+++ b/poppler/FontInfo.h
@@ -66,6 +66,10 @@ private:
   int fontsLen;
   int fontsSize;
 
+  Ref *visitedXObjects;
+  int visitedXObjectsLen;
+  int visitedXObjectsSize;
+
   void scanFonts(Dict *resDict, GooList *fontsList);
 };
 


More information about the poppler mailing list