[poppler] poppler/Gfx.cc poppler/GfxState.cc poppler/GfxState.h

Albert Astals Cid aacid at kemper.freedesktop.org
Mon Sep 25 21:46:07 UTC 2017


 poppler/Gfx.cc      |   46 ++++++++++++++++++++++++++++++++++------------
 poppler/GfxState.cc |   33 ++++++++++++++++++---------------
 poppler/GfxState.h  |   15 +++++++++------
 3 files changed, 61 insertions(+), 33 deletions(-)

New commits:
commit 2c92c7b6a828c9db8a38f079ea7a3d51c12a481d
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Sep 25 19:33:44 2017 +0200

    Fix infinite recursion on broken files
    
    Bug #102969

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];


More information about the poppler mailing list