[poppler] poppler/PDFDoc.cc poppler/PDFDoc.h

Albert Astals Cid aacid at kemper.freedesktop.org
Sun Mar 20 11:40:50 UTC 2016


 poppler/PDFDoc.cc |   42 +++++++++++++++++++++++++++++++++++++++++-
 poppler/PDFDoc.h  |    7 ++++++-
 2 files changed, 47 insertions(+), 2 deletions(-)

New commits:
commit 67bc280c4068ae9501053c06ee05341b95a5e6db
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Sun Mar 20 12:39:24 2016 +0100

    Implement sanity check for linearization usage
    
    Bug #92482

diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index f052772..9fc43e5 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..3a65ecb 100644
--- a/poppler/PDFDoc.h
+++ b/poppler/PDFDoc.h
@@ -22,7 +22,7 @@
 // Copyright (C) 2009 Kovid Goyal <kovid at kovidgoyal.net>
 // Copyright (C) 2010, 2014 Hib Eris <hib at hiberis.nl>
 // Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla at geodesic.com>
-// Copyright (C) 2011, 2013, 2014 Thomas Freitag <Thomas.Freitag at alfa.de>
+// Copyright (C) 2011, 2013, 2014, 2016 Thomas Freitag <Thomas.Freitag at alfa.de>
 // Copyright (C) 2012 Fabio D'Urso <fabiodurso at hotmail.it>
 // Copyright (C) 2013 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2013 Adam Reichold <adamreichold at myopera.com>
@@ -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;


More information about the poppler mailing list