You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
253 lines
8.4 KiB
253 lines
8.4 KiB
From accdc5be215c7ee3223e3ad21dee7708d910ef23 Mon Sep 17 00:00:00 2001
|
|
From: Albert Astals Cid <aacid@kde.org>
|
|
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<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 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
|
|
|