diff options
author | Albert Astals Cid <aacid@kde.org> | 2017-09-25 19:33:44 +0200 |
---|---|---|
committer | Albert Astals Cid <aacid@kde.org> | 2017-09-25 19:36:57 +0200 |
commit | 2c92c7b6a828c9db8a38f079ea7a3d51c12a481d (patch) | |
tree | 25afdf300dad03a28e67f0eb5b2ee91128f4a537 | |
parent | d3f12611b30e6421f05603a9838ed9131b1aa61e (diff) |
Fix infinite recursion on broken files
Bug #102969
-rw-r--r-- | poppler/Gfx.cc | 46 | ||||
-rw-r--r-- | poppler/GfxState.cc | 33 | ||||
-rw-r--r-- | poppler/GfxState.h | 15 |
3 files changed, 61 insertions, 33 deletions
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 3eea6d2a..eaef798f 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -458,9 +458,15 @@ GfxPattern *GfxResources::lookupPattern(char *name, OutputDev *out, GfxState *st for (resPtr = this; resPtr; resPtr = resPtr->next) { if (resPtr->patternDict.isDict()) { - Object obj = resPtr->patternDict.dictLookup(name); + Object obj = resPtr->patternDict.dictLookupNF(name); if (!obj.isNull()) { - pattern = GfxPattern::parse(resPtr, &obj, out, state); + Ref patternRef = { -1, -1 }; + if (obj.isRef()) { + patternRef = obj.getRef(); + obj = obj.fetch(resPtr->patternDict.getDict()->getXRef()); + } + + pattern = GfxPattern::parse(resPtr, &obj, out, state, patternRef.num); return pattern; } } @@ -2224,18 +2230,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<int>::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 b2971ec0..3e30edf0 100644 --- a/poppler/GfxState.cc +++ b/poppler/GfxState.cc @@ -3351,14 +3351,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; @@ -3371,9 +3374,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); } return pattern; } @@ -3382,7 +3385,7 @@ GfxPattern *GfxPattern::parse(GfxResources *res, Object *obj, OutputDev *out, Gf // GfxTilingPattern //------------------------------------------------------------------------ -GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { +GfxTilingPattern *GfxTilingPattern::parse(Object *patObj, int patternRefNum) { Dict *dict; int paintTypeA, tilingTypeA; double bboxA[4], matrixA[6]; @@ -3455,14 +3458,14 @@ GfxTilingPattern *GfxTilingPattern::parse(Object *patObj) { } return new GfxTilingPattern(paintTypeA, tilingTypeA, bboxA, xStepA, yStepA, - &resDictA, matrixA, patObj); + &resDictA, matrixA, patObj, patternRefNum); } 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; @@ -3485,14 +3488,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]; @@ -3523,11 +3526,11 @@ GfxShadingPattern *GfxShadingPattern::parse(GfxResources *res, Object *patObj, O } } - 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; @@ -3542,7 +3545,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]; |