From accdc5be215c7ee3223e3ad21dee7708d910ef23 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Mon, 25 Sep 2017 19:33:44 +0200 Subject: [PATCH 4/4] Fix infinite recursion on broken files Bug #102969 --- poppler/Gfx.cc | 46 ++++++++++++++++++++++++++++++++++------------ poppler/GfxState.cc | 33 ++++++++++++++++++--------------- poppler/GfxState.h | 15 +++++++++------ 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 9feac54c..66d0a24c 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -468,8 +468,14 @@ GfxPattern *GfxResources::lookupPattern(char *name, OutputDev *out, GfxState *st for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->patternDict.isDict()) { - if (!resPtr->patternDict.dictLookup(name, &obj)->isNull()) { - pattern = GfxPattern::parse(resPtr, &obj, out, state); + if (!resPtr->patternDict.dictLookupNF(name, &obj)->isNull()) { + Ref patternRef = { -1, -1 }; + if (obj.isRef()) { + patternRef = obj.getRef(); + obj.fetch(resPtr->patternDict.getDict()->getXRef(), &obj); + } + + pattern = GfxPattern::parse(resPtr, &obj, out, state, patternRef.num); obj.free(); return pattern; } @@ -2298,18 +2304,34 @@ void Gfx::doTilingPatternFill(GfxTilingPattern *tPat, xi0, yi0, xi1, yi1, xstep, ystep)) { goto restore; } else { - out->updatePatternOpacity(state); - for (yi = yi0; yi < yi1; ++yi) { - for (xi = xi0; xi < xi1; ++xi) { - x = xi * xstep; - y = yi * ystep; - m1[4] = x * m[0] + y * m[2] + m[4]; - m1[5] = x * m[1] + y * m[3] + m[5]; - drawForm(tPat->getContentStream(), tPat->getResDict(), - m1, tPat->getBBox()); + bool shouldDrawForm = gTrue; + std::set::iterator patternRefIt; + const int patternRefNum = tPat->getPatternRefNum(); + if (patternRefNum != -1) { + if (formsDrawing.find(patternRefNum) == formsDrawing.end()) { + patternRefIt = formsDrawing.insert(patternRefNum).first; + } else { + shouldDrawForm = gFalse; + } + } + + if (shouldDrawForm) { + out->updatePatternOpacity(state); + for (yi = yi0; yi < yi1; ++yi) { + for (xi = xi0; xi < xi1; ++xi) { + x = xi * xstep; + y = yi * ystep; + m1[4] = x * m[0] + y * m[2] + m[4]; + m1[5] = x * m[1] + y * m[3] + m[5]; + drawForm(tPat->getContentStream(), tPat->getResDict(), + m1, tPat->getBBox()); + } + } + out->clearPatternOpacity(state); + if (patternRefNum != -1) { + formsDrawing.erase(patternRefIt); } } - out->clearPatternOpacity(state); } // restore graphics state diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc index f61f8124..90030b10 100644 --- a/poppler/GfxState.cc +++ b/poppler/GfxState.cc @@ -3446,14 +3446,17 @@ void GfxPatternColorSpace::getDefaultColor(GfxColor *color) { // Pattern //------------------------------------------------------------------------ -GfxPattern::GfxPattern(int typeA) { - type = typeA; +GfxPattern::GfxPattern(int typeA, int patternRefNumA) + : type(typeA) + , patternRefNum(patternRefNumA) +{ + } GfxPattern::~GfxPattern() { } -GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state) { +GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state, int patternRefNum) { GfxPattern *pattern; Object obj1; @@ -3466,9 +3469,9 @@ GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, Gf } pattern = NULL; if (obj1.isInt() && obj1.getInt() == 1) { - pattern = GfxTilingPattern::parse(obj); + pattern = GfxTilingPattern::parse(obj, patternRefNum); } else if (obj1.isInt() && obj1.getInt() == 2) { - pattern = GfxShadingPattern::parse(res, obj, out, state); + pattern = GfxShadingPattern::parse(res, obj, out, state, patternRefNum); } obj1.free(); return pattern; @@ -3478,7 +3481,7 @@ GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, Gf // GfxTilingPattern //------------------------------------------------------------------------ -GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { +GfxTilingPattern *GfxTilingPattern::parse(Object *patObj, int patternRefNum) { GfxTilingPattern *pat; Dict *dict; int paintTypeA, tilingTypeA; @@ -3555,7 +3558,7 @@ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { obj1.free(); pat = new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA, - &resDictA, matrixA, patObj); + &resDictA, matrixA, patObj, patternRefNum); resDictA.free(); return pat; } @@ -3563,8 +3566,8 @@ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { GfxTilingPattern::GfxTilingPattern(int paintTypeA, int tilingTypeA, double *bboxA, double xStepA, double yStepA, Object *resDictA, double *matrixA, - Object *contentStreamA): - GfxPattern(1) + Object *contentStreamA, int patternRefNumA) : + GfxPattern(1, patternRefNumA) { int i; @@ -3589,14 +3592,14 @@ GfxTilingPattern::~GfxTilingPattern() { GfxPattern *GfxTilingPattern::copy() { return new GfxTilingPattern(paintType, tilingType, bbox, xStep, yStep, - &resDict, matrix, &contentStream); + &resDict, matrix, &contentStream, getPatternRefNum()); } //------------------------------------------------------------------------ // GfxShadingPattern //------------------------------------------------------------------------ -GfxShadingPattern *GfxShadingPattern::parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state) { +GfxShadingPattern *GfxShadingPattern::parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state, int patternRefNum) { Dict *dict; GfxShading *shadingA; double matrixA[6]; @@ -3629,11 +3632,11 @@ GfxShadingPattern *GfxShadingPattern::parse(GfxResources *res, Object *patObj, O } obj1.free(); - return new GfxShadingPattern(shadingA, matrixA); + return new GfxShadingPattern(shadingA, matrixA, patternRefNum); } -GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA): - GfxPattern(2) +GfxShadingPattern::GfxShadingPattern(GfxShading *shadingA, double *matrixA, int patternRefNumA): + GfxPattern(2, patternRefNumA) { int i; @@ -3648,7 +3651,7 @@ GfxShadingPattern::~GfxShadingPattern() { } GfxPattern *GfxShadingPattern::copy() { - return new GfxShadingPattern(shading->copy(), matrix); + return new GfxShadingPattern(shading->copy(), matrix, getPatternRefNum()); } //------------------------------------------------------------------------ diff --git a/poppler/GfxState.h b/poppler/GfxState.h index 7bcedf2a..4b13fb2a 100644 --- a/poppler/GfxState.h +++ b/poppler/GfxState.h @@ -762,18 +762,21 @@ private: class GfxPattern { public: - GfxPattern(int typeA); + GfxPattern(int typeA, int patternRefNumA); virtual ~GfxPattern(); - static GfxPattern *parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state); + static GfxPattern *parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state, int patternRefNum); virtual GfxPattern *copy() = 0; int getType() { return type; } + int getPatternRefNum() const { return patternRefNum; } + private: int type; + int patternRefNum; }; //------------------------------------------------------------------------ @@ -783,7 +786,7 @@ private: class GfxTilingPattern: public GfxPattern { public: - static GfxTilingPattern *parse(Object *patObj); + static GfxTilingPattern *parse(Object *patObj, int patternRefNum); ~GfxTilingPattern(); GfxPattern *copy() override; @@ -803,7 +806,7 @@ private: GfxTilingPattern(int paintTypeA, int tilingTypeA, double *bboxA, double xStepA, double yStepA, Object *resDictA, double *matrixA, - Object *contentStreamA); + Object *contentStreamA, int patternRefNumA); int paintType; int tilingType; @@ -821,7 +824,7 @@ private: class GfxShadingPattern: public GfxPattern { public: - static GfxShadingPattern *parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state); + static GfxShadingPattern *parse(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state, int patternRefNum); ~GfxShadingPattern(); GfxPattern *copy() override; @@ -831,7 +834,7 @@ public: private: - GfxShadingPattern(GfxShading *shadingA, double *matrixA); + GfxShadingPattern(GfxShading *shadingA, double *matrixA, int patternRefNumA); GfxShading *shading; double matrix[6]; -- 2.14.1