X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=pdf%2Fxpdf%2FCatalog.cc;h=8762cd4cb4d1a908436382fbadfc4d26b5805620;hb=8e5042edbe098c8a8b760a36a8bc35dfca4e6041;hp=1212e2eb3469ab4afe628fddfc21c0fb913b66ad;hpb=2a393c134fe3fe8eb85bf818cb7ad6ae4396322a;p=evince.git diff --git a/pdf/xpdf/Catalog.cc b/pdf/xpdf/Catalog.cc index 1212e2eb..8762cd4c 100644 --- a/pdf/xpdf/Catalog.cc +++ b/pdf/xpdf/Catalog.cc @@ -2,15 +2,16 @@ // // Catalog.cc // -// Copyright 1996-2002 Glyph & Cog, LLC +// Copyright 1996-2003 Glyph & Cog, LLC // //======================================================================== -#ifdef __GNUC__ +#include + +#ifdef USE_GCC_PRAGMAS #pragma implementation #endif -#include #include #include "gmem.h" #include "Object.h" @@ -26,7 +27,7 @@ // Catalog //------------------------------------------------------------------------ -Catalog::Catalog(XRef *xrefA, GBool printCommands) { +Catalog::Catalog(XRef *xrefA) { Object catDict, pagesDict; Object obj, obj2; int numPages0; @@ -55,13 +56,23 @@ Catalog::Catalog(XRef *xrefA, GBool printCommands) { goto err2; } pagesDict.dictLookup("Count", &obj); - if (!obj.isInt()) { + // some PDF files actually use real numbers here ("/Count 9.0") + if (!obj.isNum()) { error(-1, "Page count in top-level pages object is wrong type (%s)", obj.getTypeName()); goto err3; } - pagesSize = numPages0 = obj.getInt(); + pagesSize = numPages0 = (int)obj.getNum(); obj.free(); + // The gcc doesnt optimize this away, so this check is ok, + // even if it looks like a pagesSize != pagesSize check + if (pagesSize*sizeof(Page *)/sizeof(Page *) != pagesSize || + pagesSize*sizeof(Ref)/sizeof(Ref) != pagesSize) { + error(-1, "Invalid 'pagesSize'"); + ok = gFalse; + return; + } + pages = (Page **)gmalloc(pagesSize * sizeof(Page *)); pageRefs = (Ref *)gmalloc(pagesSize * sizeof(Ref)); for (i = 0; i < pagesSize; ++i) { @@ -69,7 +80,7 @@ Catalog::Catalog(XRef *xrefA, GBool printCommands) { pageRefs[i].num = -1; pageRefs[i].gen = -1; } - numPages = readPageTree(pagesDict.getDict(), NULL, 0, printCommands); + numPages = readPageTree(pagesDict.getDict(), NULL, 0); if (numPages != numPages0) { error(-1, "Page count in top-level pages object is incorrect"); } @@ -100,6 +111,9 @@ Catalog::Catalog(XRef *xrefA, GBool printCommands) { // get the structure tree root catDict.dictLookup("StructTreeRoot", &structTreeRoot); + // get the outline dictionary + catDict.dictLookup("Outlines", &outline); + catDict.free(); return; @@ -133,6 +147,7 @@ Catalog::~Catalog() { } metadata.free(); structTreeRoot.free(); + outline.free(); } GString *Catalog::readMetadata() { @@ -159,8 +174,7 @@ GString *Catalog::readMetadata() { return s; } -int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, - GBool printCommands) { +int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { Object kids; Object kid; Object kidRef; @@ -179,13 +193,18 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, kids.arrayGet(i, &kid); if (kid.isDict("Page")) { attrs2 = new PageAttrs(attrs1, kid.getDict()); - page = new Page(xref, start+1, kid.getDict(), attrs2, printCommands); + page = new Page(xref, start+1, kid.getDict(), attrs2); if (!page->isOk()) { ++start; goto err3; } if (start >= pagesSize) { pagesSize += 32; + if (pagesSize*sizeof(Page *)/sizeof(Page *) != pagesSize || + pagesSize*sizeof(Ref)/sizeof(Ref) != pagesSize) { + error(-1, "Invalid 'pagesSize' parameter."); + goto err3; + } pages = (Page **)grealloc(pages, pagesSize * sizeof(Page *)); pageRefs = (Ref *)grealloc(pageRefs, pagesSize * sizeof(Ref)); for (j = pagesSize - 32; j < pagesSize; ++j) { @@ -205,7 +224,7 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. } else if (kid.isDict()) { - if ((start = readPageTree(kid.getDict(), attrs1, start, printCommands)) + if ((start = readPageTree(kid.getDict(), attrs1, start)) < 0) goto err2; } else { @@ -276,6 +295,10 @@ LinkDest *Catalog::findDest(GString *name) { error(-1, "Bad named destination value"); } obj1.free(); + if (dest && !dest->isOk()) { + delete dest; + dest = NULL; + } return dest; } @@ -299,8 +322,8 @@ Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) { } else if (cmp < 0) { done = gTrue; } - name1.free(); } + name1.free(); } names.free(); if (!found)