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
