[poppler] poppler/XRef.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Sun Nov 22 10:52:47 PST 2009


 poppler/XRef.cc |  165 ++++++++++++++++++++++++++++++++------------------------
 1 file changed, 95 insertions(+), 70 deletions(-)

New commits:
commit 32de2ac62fb87570e1a59152f37b86e571a01180
Author: Ilya Gorenbein <igorenbein at finjan.com>
Date:   Sun Nov 22 19:51:54 2009 +0100

    Improve the reconstruction of the XRef
    
    Makes load a file Ilya can't share

diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index e5fd92a..3ab23d9 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -18,6 +18,7 @@
 // Copyright (C) 2006, 2008 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2007-2008 Julien Rebetez <julienr at svn.gnome.org>
 // Copyright (C) 2007 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2009 Ilya Gorenbein <igorenbein at finjan.com>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -715,6 +716,9 @@ GBool XRef::constructXRef() {
   char *p;
   int i;
   GBool gotRoot;
+  char* token = NULL;
+  bool oneCycle = true;
+  int offset = 0;
 
   gfree(entries);
   size = 0;
@@ -735,94 +739,115 @@ GBool XRef::constructXRef() {
     // skip whitespace
     while (*p && Lexer::isSpace(*p & 0xff)) ++p;
 
-    // got trailer dictionary
-    if (!strncmp(p, "trailer", 7)) {
-      obj.initNull();
-      parser = new Parser(NULL,
+    oneCycle = true;
+    offset = 0;
+
+    while( ( token = strstr( p, "endobj" ) ) || oneCycle ) {
+      oneCycle = false;
+
+      if( token ) {
+        oneCycle = true;
+        token[0] = '\0'; 
+        offset = token - p;
+      }
+
+      // got trailer dictionary
+      if (!strncmp(p, "trailer", 7)) {
+        obj.initNull();
+        parser = new Parser(NULL,
 		 new Lexer(NULL,
 		   str->makeSubStream(pos + 7, gFalse, 0, &obj)),
 		 gFalse);
-      parser->getObj(&newTrailerDict);
-      if (newTrailerDict.isDict()) {
-	newTrailerDict.dictLookupNF("Root", &obj);
-	if (obj.isRef()) {
-	  rootNum = obj.getRefNum();
-	  rootGen = obj.getRefGen();
-	  if (!trailerDict.isNone()) {
-	    trailerDict.free();
+        parser->getObj(&newTrailerDict);
+        if (newTrailerDict.isDict()) {
+	  newTrailerDict.dictLookupNF("Root", &obj);
+	  if (obj.isRef()) {
+	    rootNum = obj.getRefNum();
+	    rootGen = obj.getRefGen();
+	    if (!trailerDict.isNone()) {
+	      trailerDict.free();
+	    }
+	    newTrailerDict.copy(&trailerDict);
+	    gotRoot = gTrue;
 	  }
-	  newTrailerDict.copy(&trailerDict);
-	  gotRoot = gTrue;
-	}
-	obj.free();
-      }
-      newTrailerDict.free();
-      delete parser;
+	  obj.free();
+        }
+        newTrailerDict.free();
+        delete parser;
 
-    // look for object
-    } else if (isdigit(*p)) {
-      num = atoi(p);
-      if (num > 0) {
-	do {
-	  ++p;
-	} while (*p && isdigit(*p));
-	if (isspace(*p)) {
+      // look for object
+      } else if (isdigit(*p)) {
+        num = atoi(p);
+        if (num > 0) {
 	  do {
 	    ++p;
-	  } while (*p && isspace(*p));
-	  if (isdigit(*p)) {
-	    gen = atoi(p);
+	  } while (*p && isdigit(*p));
+	  if (isspace(*p)) {
 	    do {
 	      ++p;
-	    } while (*p && isdigit(*p));
-	    if (isspace(*p)) {
+	    } while (*p && isspace(*p));
+	    if (isdigit(*p)) {
+	      gen = atoi(p);
 	      do {
-		++p;
-	      } while (*p && isspace(*p));
-	      if (!strncmp(p, "obj", 3)) {
-		if (num >= size) {
-		  newSize = (num + 1 + 255) & ~255;
-		  if (newSize < 0) {
-		    error(-1, "Bad object number");
-		    return gFalse;
+	        ++p;
+	      } while (*p && isdigit(*p));
+	      if (isspace(*p)) {
+	        do {
+		  ++p;
+	        } while (*p && isspace(*p));
+	        if (!strncmp(p, "obj", 3)) {
+		  if (num >= size) {
+		    newSize = (num + 1 + 255) & ~255;
+		    if (newSize < 0) {
+		      error(-1, "Bad object number");
+		      return gFalse;
+		    }
+		    if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) {
+		      error(-1, "Invalid 'obj' parameters.");
+		      return gFalse;
+		    }
+		    entries = (XRefEntry *)
+		        greallocn(entries, newSize, sizeof(XRefEntry));
+		    for (i = size; i < newSize; ++i) {
+		      entries[i].offset = 0xffffffff;
+		      entries[i].type = xrefEntryFree;
+		      entries[i].obj.initNull ();
+		      entries[i].updated = false;
+		    }
+		    size = newSize;
 		  }
-		  if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) {
-		    error(-1, "Invalid 'obj' parameters.");
-		    return gFalse;
+		  if (entries[num].type == xrefEntryFree ||
+		      gen >= entries[num].gen) {
+		    entries[num].offset = pos - start;
+		    entries[num].gen = gen;
+		    entries[num].type = xrefEntryUncompressed;
 		  }
-		  entries = (XRefEntry *)
-		      greallocn(entries, newSize, sizeof(XRefEntry));
-		  for (i = size; i < newSize; ++i) {
-		    entries[i].offset = 0xffffffff;
-		    entries[i].type = xrefEntryFree;
-		    entries[i].obj.initNull ();
-		    entries[i].updated = false;
-		  }
-		  size = newSize;
-		}
-		if (entries[num].type == xrefEntryFree ||
-		    gen >= entries[num].gen) {
-		  entries[num].offset = pos - start;
-		  entries[num].gen = gen;
-		  entries[num].type = xrefEntryUncompressed;
-		}
+	        }
 	      }
 	    }
 	  }
-	}
-      }
-
-    } else if (!strncmp(p, "endstream", 9)) {
-      if (streamEndsLen == streamEndsSize) {
-	streamEndsSize += 64;
-        if (streamEndsSize >= INT_MAX / (int)sizeof(int)) {
-          error(-1, "Invalid 'endstream' parameter.");
-          return gFalse;
         }
-	streamEnds = (Guint *)greallocn(streamEnds,
+
+      } else if (!strncmp(p, "endstream", 9)) {
+        if (streamEndsLen == streamEndsSize) {
+	  streamEndsSize += 64;
+          if (streamEndsSize >= INT_MAX / (int)sizeof(int)) {
+            error(-1, "Invalid 'endstream' parameter.");
+            return gFalse;
+          }
+	  streamEnds = (Guint *)greallocn(streamEnds,
 					streamEndsSize, sizeof(int));
+        }
+        streamEnds[streamEndsLen++] = pos;
+      }
+      if( token ) {
+        p = token + 6;// strlen( "endobj" ) = 6
+        pos += offset + 6;// strlen( "endobj" ) = 6
+        while (*p && Lexer::isSpace(*p & 0xff)) {
+          ++p;
+          ++pos;
+        }
       }
-      streamEnds[streamEndsLen++] = pos;
     }
   }
 


More information about the poppler mailing list