Commit 8dc7afae authored by Albert Astals Cid's avatar Albert Astals Cid

Some documents have loops in XObject dictionaries, make sure we don't get in...

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
parent 9fb17c95
......@@ -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();
......
......@@ -66,6 +66,10 @@ private:
int fontsLen;
int fontsSize;
Ref *visitedXObjects;
int visitedXObjectsLen;
int visitedXObjectsSize;
void scanFonts(Dict *resDict, GooList *fontsList);
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment