diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 80e1205..b098f7b 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -786,7 +786,7 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { } // Attempt to construct an xref table for a damaged file. -GBool XRef::constructXRef(GBool *wasReconstructed) { +GBool XRef::constructXRef(GBool *wasReconstructed, GBool needCatalogDict) { Parser *parser; Object newTrailerDict, obj; char buf[256]; @@ -846,7 +846,7 @@ GBool XRef::constructXRef(GBool *wasReconstructed) { parser->getObj(&newTrailerDict); if (newTrailerDict.isDict()) { newTrailerDict.dictLookupNF("Root", &obj); - if (obj.isRef()) { + if (obj.isRef() && (!gotRoot || !needCatalogDict) && rootNum != obj.getRefNum()) { rootNum = obj.getRefNum(); rootGen = obj.getRefGen(); if (!trailerDict.isNone()) { @@ -1016,6 +1016,16 @@ GBool XRef::okToAssemble(GBool ignoreOwnerPW) { return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAssemble); } +Object *XRef::getCatalog(Object *catalog) { + Object *obj = fetch(rootNum, rootGen, catalog); + if (obj->isDict()) { + return obj; + } + GBool wasReconstructed = false; + GBool ok = constructXRef(&wasReconstructed, gTrue); + return (ok) ? fetch(rootNum, rootGen, catalog) : obj; +} + Object *XRef::fetch(int num, int gen, Object *obj, int recursion) { XRefEntry *e; Parser *parser; diff --git a/poppler/XRef.h b/poppler/XRef.h index 78c1782..310572f 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -131,7 +131,7 @@ public: int getPermFlags() { return permFlags; } // Get catalog object. - Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } + Object *getCatalog(Object *obj); // Fetch an indirect reference. Object *fetch(int num, int gen, Object *obj, int recursion = 0); @@ -214,7 +214,7 @@ private: GBool readXRefTable(Parser *parser, Guint *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum); GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n); GBool readXRefStream(Stream *xrefStr, Guint *pos); - GBool constructXRef(GBool *wasReconstructed); + GBool constructXRef(GBool *wasReconstructed, GBool needCatalogDict = gFalse); GBool parseEntry(Guint offset, XRefEntry *entry); void readXRefUntil(int untilEntryNum, std::vector *xrefStreamObjsNum = NULL); void markUnencrypted(Object *obj);