[poppler] Branch 'poppler-0.12' - poppler/XRef.cc
Albert Astals Cid
aacid at kemper.freedesktop.org
Sun Nov 22 10:53:19 PST 2009
poppler/XRef.cc | 165 ++++++++++++++++++++++++++++++++------------------------
1 file changed, 95 insertions(+), 70 deletions(-)
New commits:
commit ac1e46da77e03ca193af75ca03d5e0a05c16200e
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