diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2019-05-03 04:51:31 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2019-05-03 04:51:31 +0000 |
commit | e203cb2b40427e96c870fbbe5c176b3cf17975f4 (patch) | |
tree | 7e3c875f5c19af41d1f0a9eb7e7e7fac2fe55c5d /Build/source/libs/xpdf/xpdf-src | |
parent | 31ad85f20058d3169309edc25fb1a7579c6e1556 (diff) |
xpdf 4.01.01
git-svn-id: svn://tug.org/texlive/trunk@50962 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src')
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/CHANGES | 11 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/INSTALL | 4 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/README | 4 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/splash/Splash.cc | 17 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc | 13 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc | 4 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc | 18 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h | 2 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc | 1 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc | 24 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc | 12 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc | 4 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/config.h | 8 | ||||
-rw-r--r-- | Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc | 159 |
14 files changed, 183 insertions, 98 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/CHANGES b/Build/source/libs/xpdf/xpdf-src/CHANGES index eef2a67940b..0114145987c 100644 --- a/Build/source/libs/xpdf/xpdf-src/CHANGES +++ b/Build/source/libs/xpdf/xpdf-src/CHANGES @@ -2539,3 +2539,14 @@ Handle a null font name in PSOutputDev::setupEmbeddedType1Font. [Thanks to r4xis for the bug report.] Check for invalid quant table indexes in the DCT decoder. [Thanks to r4xis for the bug report.] + +4.01.01 (2019-mar-14) +--------------------- +The PDFDoc(BaseStream) initializer wasn't working correctly. +Fixed a missing array bounds check in PSOutputDev. [Thanks to + Loginsoft for the bug report.] +If the "U" string used for RC4 decryption is short, Adobe apparently + zero-pads it, so Xpdf now does the same. +Pdffonts now checks more carefully for loops between objects. +Fixed a problem parsing large real numbers. [Thanks to Loginsoft for + the bug report.] diff --git a/Build/source/libs/xpdf/xpdf-src/INSTALL b/Build/source/libs/xpdf/xpdf-src/INSTALL index 2df3e7fc2e9..f45ce6bad37 100644 --- a/Build/source/libs/xpdf/xpdf-src/INSTALL +++ b/Build/source/libs/xpdf/xpdf-src/INSTALL @@ -1,8 +1,8 @@ Xpdf ==== -version 4.01 -2019-feb-18 +version 4.01.01 +2019-mar-14 The Xpdf software and documentation are copyright 1996-2019 Glyph & Cog, LLC. diff --git a/Build/source/libs/xpdf/xpdf-src/README b/Build/source/libs/xpdf/xpdf-src/README index 56a42589fdb..25e4f110eba 100644 --- a/Build/source/libs/xpdf/xpdf-src/README +++ b/Build/source/libs/xpdf/xpdf-src/README @@ -1,8 +1,8 @@ Xpdf ==== -version 4.01 -2019-feb-18 +version 4.01.01 +2019-mar-14 The Xpdf software and documentation are copyright 1996-2019 Glyph & Cog, LLC. diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc index 30961066a23..77718abbe70 100644 --- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc +++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc @@ -4567,7 +4567,8 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData, SplashCoord xMin, yMin, xMax, yMax, t; SplashCoord mi0, mi1, mi2, mi3, mi4, mi5, det; SplashCoord ix, iy, sx, sy, pix0, pix1; - int rowSize, xMinI, yMinI, xMaxI, yMaxI, x, y, x0, y0, x1, y1, tt, i; + SplashBitmapRowSize rowSize; + int xMinI, yMinI, xMaxI, yMaxI, x, y, x0, y0, x1, y1, tt, i; // compute the bbox of the target quadrilateral xMin = xMax = mat[4]; @@ -4653,7 +4654,7 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData, } else { rowSize = srcWidth * nComps; } - unscaledImage = (SplashColorPtr)gmallocn(srcHeight, rowSize); + unscaledImage = (SplashColorPtr)gmallocn64(srcHeight, rowSize); if (srcAlpha) { unscaledAlpha = (Guchar *)gmallocn(srcHeight, srcWidth); for (y = 0, p = unscaledImage, alphaPtr = unscaledAlpha; @@ -4663,7 +4664,7 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData, } } else { unscaledAlpha = NULL; - for (y = 0, p = unscaledImage; y < srcHeight; ++y, p += srcWidth * nComps) { + for (y = 0, p = unscaledImage; y < srcHeight; ++y, p += rowSize) { (*src)(srcData, p, NULL); } } @@ -4698,10 +4699,10 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData, if (y1 >= srcHeight) { y1 = srcHeight - 1; } - q00 = &unscaledImage[(y0 * srcWidth + x0) * nComps]; - q01 = &unscaledImage[(y0 * srcWidth + x1) * nComps]; - q10 = &unscaledImage[(y1 * srcWidth + x0) * nComps]; - q11 = &unscaledImage[(y1 * srcWidth + x1) * nComps]; + q00 = &unscaledImage[y0 * rowSize + (SplashBitmapRowSize)x0 * nComps]; + q01 = &unscaledImage[y0 * rowSize + (SplashBitmapRowSize)x1 * nComps]; + q10 = &unscaledImage[y1 * rowSize + (SplashBitmapRowSize)x0 * nComps]; + q11 = &unscaledImage[y1 * rowSize + (SplashBitmapRowSize)x1 * nComps]; for (i = 0; i < nComps; ++i) { pix0 = ((SplashCoord)1 - sx) * (int)*q00++ + sx * (int)*q01++; pix1 = ((SplashCoord)1 - sx) * (int)*q10++ + sx * (int)*q11++; @@ -4730,7 +4731,7 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData, x0 = splashFloor(ix); y0 = splashFloor(iy); if (x0 >= 0 && x0 < srcWidth && y0 >= 0 && y0 < srcHeight) { - q = &unscaledImage[(y0 * srcWidth + x0) * nComps]; + q = &unscaledImage[y0 * rowSize + (SplashBitmapRowSize)x0 * nComps]; for (i = 0; i < nComps; ++i) { *p++ = *q++; } diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc index 9bbafac6839..1d312e97428 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/AcroForm.cc @@ -1542,6 +1542,13 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict, fontSize = atof(tok->getCString()); } else { error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string"); + fontSize = 10; + if (!daToks) { + daToks = new GList(); + } + daToks->append(new GString("/xpdf_default_font")); + daToks->append(new GString("10")); + daToks->append(new GString("Tf")); } // setup @@ -1603,7 +1610,11 @@ void AcroFormField::drawText(GString *text, GString *da, GfxFontDict *fontDict, // starting y coordinate // (note: each line of text starts with a Td operator that moves // down a line) - y = dy - 3; + if (dy > fontSize + 6) { + y = dy - 3; + } else { + y = 0.5 * dy - 0.4 * fontSize + fontSize; + } // set the font matrix if (tmPos >= 0) { diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc index 283a070b576..05e9df9f24c 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/Lexer.cc @@ -179,7 +179,9 @@ Object *Lexer::getObj(Object *obj) { if (isdigit(c)) { getChar(); xi = xi * 10 + (c - '0'); - xf = xf * 10 + (c - '0'); + if (xf < 1e20) { + xf = xf * 10 + (c - '0'); + } } else if (c == '.') { getChar(); goto doReal; diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc index 53ec6634bc6..70919f48947 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.cc @@ -692,6 +692,24 @@ void PDFCore::scrollToBottomRight() { tileMap->getPageBottomY(tileMap->getLastPage())); } +void PDFCore::scrollToCentered(int page, double x, double y) { + int wx, wy, sx, sy; + + startUpdate(); + + // scroll to the requested page + state->setScrollPosition(page, tileMap->getPageLeftX(page), + tileMap->getPageTopY(page)); + + // scroll the requested point to the center of the window + cvtUserToWindow(page, x, y, &wx, &wy); + sx = state->getScrollX() + wx - state->getWinW() / 2; + sy = state->getScrollY() + wy - state->getWinH() / 2; + state->setScrollPosition(page, sx, sy); + + finishUpdate(gTrue, gFalse); +} + void PDFCore::setZoom(double zoom) { int page; diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h index 056a6c1432e..0fa089ff949 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFCore.h @@ -148,6 +148,8 @@ public: virtual void scrollToBottomEdge(); virtual void scrollToTopLeft(); virtual void scrollToBottomRight(); + // Scroll so that (page, x, y) is centered in the window. + virtual void scrollToCentered(int page, double x, double y); virtual void setZoom(double zoom); virtual void zoomToRect(int page, double ulx, double uly, double lrx, double lry); diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc index ce73e517bac..8bc14eb47ad 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PDFDoc.cc @@ -232,6 +232,7 @@ PDFDoc::PDFDoc(BaseStream *strA, GString *ownerPassword, fileNameU = NULL; #endif } + str = strA; ok = setup(ownerPassword, userPassword); } diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc index aa0b172db9b..15a2a233990 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/PSOutputDev.cc @@ -1924,8 +1924,12 @@ void PSOutputDev::setupResources(Dict *resDict) { skip = gFalse; if ((xObjDict.dictGetValNF(i, &xObjRef)->isRef())) { ref0 = xObjRef.getRef(); - skip = (GBool)visitedResources[ref0.num]; - visitedResources[ref0.num] = 1; + if (ref0.num < 0 || ref0.num >= xref->getNumObjects()) { + skip = gTrue; + } else { + skip = (GBool)visitedResources[ref0.num]; + visitedResources[ref0.num] = 1; + } } if (!skip) { @@ -1956,8 +1960,12 @@ void PSOutputDev::setupResources(Dict *resDict) { skip = gFalse; if ((patDict.dictGetValNF(i, &patRef)->isRef())) { ref0 = patRef.getRef(); - skip = (GBool)visitedResources[ref0.num]; - visitedResources[ref0.num] = 1; + if (ref0.num < 0 || ref0.num >= xref->getNumObjects()) { + skip = gTrue; + } else { + skip = (GBool)visitedResources[ref0.num]; + visitedResources[ref0.num] = 1; + } } if (!skip) { @@ -1988,8 +1996,12 @@ void PSOutputDev::setupResources(Dict *resDict) { skip = gFalse; if ((gsDict.dictGetValNF(i, &gsRef)->isRef())) { ref0 = gsRef.getRef(); - skip = (GBool)visitedResources[ref0.num]; - visitedResources[ref0.num] = 1; + if (ref0.num < 0 || ref0.num >= xref->getNumObjects()) { + skip = gTrue; + } else { + skip = (GBool)visitedResources[ref0.num]; + visitedResources[ref0.num] = 1; + } } if (!skip) { diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc index 4ceddea0561..4a7d0954c40 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SecurityHandler.cc @@ -235,7 +235,7 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA, if (ownerKeyObj.getString()->getLength() != 32 || userKeyObj.getString()->getLength() != 32) { error(errSyntaxError, -1, "Invalid encryption key length"); - goto done; + // this is non-fatal -- see below } } else if (encRevision <= 6) { // the spec says 48 bytes, but Acrobat pads them out longer @@ -252,6 +252,16 @@ StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA, permFlags = permObj.getInt(); ownerKey = ownerKeyObj.getString()->copy(); userKey = userKeyObj.getString()->copy(); + if (encRevision <= 4) { + // Adobe apparently zero-pads the U value (and maybe the O value?) + // if it's short + while (ownerKey->getLength() < 32) { + ownerKey->append((char)0x00); + } + while (userKey->getLength() < 32) { + userKey->append((char)0x00); + } + } if (encVersion >= 1 && encVersion <= 2 && encRevision >= 2 && encRevision <= 3) { if (fileIDObj.isArray()) { diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc index 770e54780f1..df2e2b289cc 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc @@ -4175,8 +4175,8 @@ void SplashOutputDev::reduceImageResolution(Stream *str, double *ctm, if (str->getKind() == strJPX && *width * *height > 10000000) { - sw = (double)*width / (fabs(ctm[2]) + fabs(ctm[3])); - sh = (double)*height / (fabs(ctm[0]) + fabs(ctm[1])); + sw = (double)*width / (fabs(ctm[0]) + fabs(ctm[1])); + sh = (double)*height / (fabs(ctm[2]) + fabs(ctm[3])); if (sw > 8 && sh > 8) { reduction = 3; } else if (sw > 4 && sh > 4) { diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h index b31590e8937..f5c566e9696 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/config.h +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/config.h @@ -14,14 +14,14 @@ //------------------------------------------------------------------------ // xpdf version -#define xpdfVersion "4.01" +#define xpdfVersion "4.01.01" #define xpdfVersionNum 4.01 #define xpdfMajorVersion 4 #define xpdfMinorVersion 1 -#define xpdfUpdateVersion 0 +#define xpdfUpdateVersion 1 #define xpdfMajorVersionStr "4" #define xpdfMinorVersionStr "1" -#define xpdfUpdateVersionStr "0" +#define xpdfUpdateVersionStr "1" // supported PDF version #define supportedPDFVersionStr "2.0" @@ -31,7 +31,7 @@ #define xpdfCopyright "Copyright 1996-2019 Glyph & Cog, LLC" // Windows resource file stuff -#define winxpdfVersion "WinXpdf 4.01" +#define winxpdfVersion "WinXpdf 4.01.01" #define xpdfCopyrightAmp "Copyright 1996-2019 Glyph && Cog, LLC" //------------------------------------------------------------------------ diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc index 59925094002..7df38cc11d7 100644 --- a/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc +++ b/Build/source/libs/xpdf/xpdf-src/xpdf/pdffonts.cc @@ -46,6 +46,7 @@ static const char *fontTypeNames[] = { static void scanFonts(Object *obj, PDFDoc *doc); static void scanFonts(Dict *resDict, PDFDoc *doc); static void scanFont(GfxFont *font, PDFDoc *doc); +static GBool checkObject(Object *in, Object *out); static int firstPage = 1; static int lastPage = 0; @@ -85,16 +86,16 @@ static ArgDesc argDesc[] = { {NULL} }; +static PDFDoc *doc; + static Ref *fonts; static int fontsLen; static int fontsSize; -static Ref *seenObjs; -static int seenObjsLen; -static int seenObjsSize; +static char *seenObjs; +static int numObjects; int main(int argc, char *argv[]) { - PDFDoc *doc; char *fileName; GString *ownerPW, *userPW; GBool ok; @@ -166,8 +167,9 @@ int main(int argc, char *argv[]) { } fonts = NULL; fontsLen = fontsSize = 0; - seenObjs = NULL; - seenObjsLen = seenObjsSize = 0; + numObjects = doc->getXRef()->getNumObjects(); + seenObjs = (char *)gmalloc(numObjects); + memset(seenObjs, 0, numObjects); for (pg = firstPage; pg <= lastPage; ++pg) { page = doc->getCatalog()->getPage(pg); if ((resDict = page->getResourceDict())) { @@ -220,35 +222,18 @@ int main(int argc, char *argv[]) { static void scanFonts(Object *obj, PDFDoc *doc) { Object obj2; - int i; - if (obj->isRef()) { - for (i = 0; i < seenObjsLen; ++i) { - if (obj->getRefNum() == seenObjs[i].num && - obj->getRefGen() == seenObjs[i].gen) { - return; - } - } - if (seenObjsLen == seenObjsSize) { - if (seenObjsSize <= INT_MAX - 32) { - seenObjsSize += 32; - } else { - // let greallocn throw an exception - seenObjsSize = -1; - } - seenObjs = (Ref *)greallocn(seenObjs, seenObjsSize, sizeof(Ref)); - } - seenObjs[seenObjsLen++] = obj->getRef(); - } - if (obj->fetch(doc->getXRef(), &obj2)->isDict()) { + if (checkObject(obj, &obj2) && obj2.isDict()) { scanFonts(obj2.getDict(), doc); } obj2.free(); } static void scanFonts(Dict *resDict, PDFDoc *doc) { - Object obj1, obj2, xObjDict, xObj; - Object patternDict, pattern, gsDict, gs, smask, smaskGroup, resObj; + Object fontDict1, fontDict2, xObjDict1, xObjDict2, xObj1, xObj2; + Object patternDict1, patternDict2, pattern1, pattern2; + Object gsDict1, gsDict2, gs1, gs2, smask1, smask2, smaskGroup1, smaskGroup2; + Object resObj; Ref r; GfxFontDict *gfxFontDict; GfxFont *font; @@ -256,79 +241,90 @@ static void scanFonts(Dict *resDict, PDFDoc *doc) { // scan the fonts in this resource dictionary gfxFontDict = NULL; - resDict->lookupNF("Font", &obj1); - if (obj1.isRef()) { - obj1.fetch(doc->getXRef(), &obj2); - if (obj2.isDict()) { - r = obj1.getRef(); - gfxFontDict = new GfxFontDict(doc->getXRef(), &r, obj2.getDict()); + resDict->lookupNF("Font", &fontDict1); + if (checkObject(&fontDict1, &fontDict2) && fontDict2.isDict()) { + if (fontDict1.isRef()) { + r = fontDict1.getRef(); + gfxFontDict = new GfxFontDict(doc->getXRef(), &r, fontDict2.getDict()); + } else { + gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, fontDict2.getDict()); } - obj2.free(); - } else if (obj1.isDict()) { - gfxFontDict = new GfxFontDict(doc->getXRef(), NULL, obj1.getDict()); - } - if (gfxFontDict) { - for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { - if ((font = gfxFontDict->getFont(i))) { - scanFont(font, doc); + if (gfxFontDict) { + for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { + if ((font = gfxFontDict->getFont(i))) { + scanFont(font, doc); + } } + delete gfxFontDict; } - delete gfxFontDict; } - obj1.free(); + fontDict2.free(); + fontDict1.free(); // recursively scan any resource dictionaries in XObjects in this // resource dictionary - resDict->lookup("XObject", &xObjDict); - if (xObjDict.isDict()) { - for (i = 0; i < xObjDict.dictGetLength(); ++i) { - xObjDict.dictGetVal(i, &xObj); - if (xObj.isStream()) { - xObj.streamGetDict()->lookupNF("Resources", &resObj); + resDict->lookupNF("XObject", &xObjDict1); + if (checkObject(&xObjDict1, &xObjDict2) && xObjDict2.isDict()) { + for (i = 0; i < xObjDict2.dictGetLength(); ++i) { + xObjDict2.dictGetValNF(i, &xObj1); + if (checkObject(&xObj1, &xObj2) && xObj2.isStream()) { + xObj2.streamGetDict()->lookupNF("Resources", &resObj); scanFonts(&resObj, doc); resObj.free(); } - xObj.free(); + xObj2.free(); + xObj1.free(); } } - xObjDict.free(); + xObjDict2.free(); + xObjDict1.free(); // recursively scan any resource dictionaries in Patterns in this // resource dictionary - resDict->lookup("Pattern", &patternDict); - if (patternDict.isDict()) { - for (i = 0; i < patternDict.dictGetLength(); ++i) { - patternDict.dictGetVal(i, &pattern); - if (pattern.isStream()) { - pattern.streamGetDict()->lookupNF("Resources", &resObj); + resDict->lookupNF("Pattern", &patternDict1); + if (checkObject(&patternDict1, &patternDict2) && patternDict2.isDict()) { + for (i = 0; i < patternDict2.dictGetLength(); ++i) { + patternDict2.dictGetValNF(i, &pattern1); + if (checkObject(&pattern1, &pattern2) && pattern2.isStream()) { + pattern2.streamGetDict()->lookupNF("Resources", &resObj); scanFonts(&resObj, doc); resObj.free(); } - pattern.free(); + pattern2.free(); + pattern1.free(); } } - patternDict.free(); + patternDict2.free(); + patternDict1.free(); // recursively scan any resource dictionaries in ExtGStates in this // resource dictionary - resDict->lookup("ExtGState", &gsDict); - if (gsDict.isDict()) { - for (i = 0; i < gsDict.dictGetLength(); ++i) { - if (gsDict.dictGetVal(i, &gs)->isDict()) { - if (gs.dictLookup("SMask", &smask)->isDict()) { - if (smask.dictLookup("G", &smaskGroup)->isStream()) { - smaskGroup.streamGetDict()->lookupNF("Resources", &resObj); + resDict->lookupNF("ExtGState", &gsDict1); + if (checkObject(&gsDict1, &gsDict2) && gsDict2.isDict()) { + for (i = 0; i < gsDict2.dictGetLength(); ++i) { + gsDict1.dictGetValNF(i, &gs1); + if (checkObject(&gs1, &gs2) && gs2.isDict()) { + gs2.dictLookupNF("SMask", &smask1); + if (checkObject(&smask1, &smask2) && smask2.isDict()) { + smask2.dictLookupNF("G", &smaskGroup1); + if (checkObject(&smaskGroup1, &smaskGroup2) && + smaskGroup2.isStream()) { + smaskGroup2.streamGetDict()->lookupNF("Resources", &resObj); scanFonts(&resObj, doc); resObj.free(); } - smaskGroup.free(); + smaskGroup2.free(); + smaskGroup1.free(); } - smask.free(); + smask2.free(); + smask1.free(); } - gs.free(); + gs2.free(); + gs1.free(); } } - gsDict.free(); + gsDict2.free(); + gsDict1.free(); } static void scanFont(GfxFont *font, PDFDoc *doc) { @@ -432,3 +428,24 @@ static void scanFont(GfxFont *font, PDFDoc *doc) { } fonts[fontsLen++] = *font->getID(); } + +static GBool checkObject(Object *in, Object *out) { + int objNum; + + if (!in->isRef()) { + in->copy(out); + return gTrue; + } + objNum = in->getRefNum(); + if (objNum < 0 || objNum >= numObjects) { + out->initNull(); + return gTrue; + } + if (seenObjs[objNum]) { + out->initNull(); + return gFalse; + } + seenObjs[objNum] = (char)1; + in->fetch(doc->getXRef(), out); + return gTrue; +} |