diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index f052772..7e3e338 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -544,10 +544,50 @@ Linearization *PDFDoc::getLinearization() { if (!linearization) { linearization = new Linearization(str); + linearizationState = 0; } return linearization; } +GBool PDFDoc::checkLinearization() { + if (linearization == NULL) + return gFalse; + if (linearizationState == 1) + return gTrue; + if (linearizationState == 2) + return gFalse; + if (!hints) { + hints = new Hints(str, linearization, getXRef(), secHdlr); + } + for (int page = 1; page <= linearization->getNumPages(); page++) { + Object obj; + Ref pageRef; + + pageRef.num = hints->getPageObjectNum(page); + if (!pageRef.num) { + linearizationState = 2; + return gFalse; + } + + // check for bogus ref - this can happen in corrupted PDF files + if (pageRef.num < 0 || pageRef.num >= xref->getNumObjects()) { + linearizationState = 2; + return gFalse; + } + + pageRef.gen = xref->getEntry(pageRef.num)->gen; + xref->fetch(pageRef.num, pageRef.gen, &obj); + if (!obj.isDict("Page")) { + obj.free(); + linearizationState = 2; + return gFalse; + } + obj.free(); + } + linearizationState = 1; + return gTrue; +} + GBool PDFDoc::isLinearized(GBool tryingToReconstruct) { if ((str->getLength()) && (getLinearization()->getLength() == str->getLength())) @@ -1963,7 +2003,7 @@ Page *PDFDoc::getPage(int page) { if ((page < 1) || page > getNumPages()) return NULL; - if (isLinearized()) { + if (isLinearized() && checkLinearization()) { pdfdocLocker(); if (!pageCache) { pageCache = (Page **) gmallocn(getNumPages(), sizeof(Page *)); diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 0bb15c4..052ca77 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -111,6 +111,7 @@ public: // Get the linearization table. Linearization *getLinearization(); + GBool checkLinearization(); // Get the xref table. XRef *getXRef() { return xref; } @@ -324,6 +325,10 @@ private: int pdfMajorVersion; int pdfMinorVersion; Linearization *linearization; + // linearizationState = 0: unchecked + // linearizationState = 1: checked and valid + // linearizationState = 2: checked and invalid + int linearizationState; XRef *xref; SecurityHandler *secHdlr; Catalog *catalog;