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

New commits:
commit 32de2ac62fb87570e1a59152f37b86e571a01180
Author: Ilya Gorenbein <[email protected]>
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 <[email protected]>
 // Copyright (C) 2007-2008 Julien Rebetez <[email protected]>
 // Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+// Copyright (C) 2009 Ilya Gorenbein <[email protected]>
 //
 // 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;
     }
   }
 
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to